blob: df1cbab7c3f80fcd211ab4603dc15b5fb2ba0bdc [file] [log] [blame]
Zhenkai Zhu6cc2c812012-03-05 19:48:46 -08001/* -*- 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>
Chaoyi Bian3e1eb162012-04-03 16:59:32 -070019 * Chaoyi Bian <bcy@pku.edu.cn>
Zhenkai Zhu6cc2c812012-03-05 19:48:46 -080020 * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
21 */
Chaoyi Bian3e6e5142012-03-06 22:32:19 -080022
23#include "sync-ccnx-wrapper.h"
Alexander Afanasyev50f7e9f2012-10-08 00:20:42 -070024
25extern "C" {
26#include <ccn/fetch.h>
27}
28
Alexander Afanasyev4f9ea482012-03-15 11:57:29 -070029#include "sync-log.h"
Chaoyi Bian3e6e5142012-03-06 22:32:19 -080030#include <poll.h>
Zhenkai Zhu009ff792012-03-09 12:37:52 -080031#include <boost/throw_exception.hpp>
Alexander Afanasyev4f9ea482012-03-15 11:57:29 -070032#include <boost/date_time/posix_time/posix_time.hpp>
Alexander Afanasyev3a6c2252012-10-05 16:10:44 -070033#include <boost/random.hpp>
34
35#include "sync-scheduler.h"
Alexander Afanasyev4f9ea482012-03-15 11:57:29 -070036
Chaoyi Bian95a58c32012-03-09 15:43:59 -080037typedef boost::error_info<struct tag_errmsg, std::string> errmsg_info_str;
Alexander Afanasyev387ac952012-03-11 23:49:27 -070038typedef boost::error_info<struct tag_errmsg, int> errmsg_info_int;
Chaoyi Bian3e6e5142012-03-06 22:32:19 -080039
Alexander Afanasyev60126e02012-10-05 16:54:42 -070040
Chaoyi Bian3e6e5142012-03-06 22:32:19 -080041using namespace std;
42using namespace boost;
43
Alexander Afanasyev4f9ea482012-03-15 11:57:29 -070044INIT_LOGGER ("CcnxWrapper");
45
Chaoyi Bian3e6e5142012-03-06 22:32:19 -080046namespace Sync {
47
Alexander Afanasyev60126e02012-10-05 16:54:42 -070048boost::shared_ptr<CcnxWrapper> CcnxWrapper::s_wrapper;
49
Alexander Afanasyev2247b302012-03-14 14:11:54 -070050#ifdef _DEBUG_WRAPPER_
51CcnxWrapper::CcnxWrapper(char c)
52#else
Chaoyi Bian3e6e5142012-03-06 22:32:19 -080053CcnxWrapper::CcnxWrapper()
Alexander Afanasyev2247b302012-03-14 14:11:54 -070054#endif
Alexander Afanasyev1285b382012-03-08 16:40:27 -080055 : m_handle (0)
56 , m_keyStore (0)
57 , m_keyLoactor (0)
58 , m_running (true)
Alexander Afanasyev3a6c2252012-10-05 16:10:44 -070059 , m_connected (false)
Chaoyi Bian3e6e5142012-03-06 22:32:19 -080060{
Alexander Afanasyev2247b302012-03-14 14:11:54 -070061#ifdef _DEBUG_WRAPPER_
62 m_c = c;
63#endif
Zhenkai Zhu26cd6e32012-10-05 13:10:58 -070064 connectCcnd();
Alexander Afanasyev2c180772012-03-13 23:58:46 -070065 initKeyStore ();
66 createKeyLocator ();
Alexander Afanasyev1285b382012-03-08 16:40:27 -080067 m_thread = thread (&CcnxWrapper::ccnLoop, this);
Chaoyi Bian3e6e5142012-03-06 22:32:19 -080068}
69
Zhenkai Zhu26cd6e32012-10-05 13:10:58 -070070void
71CcnxWrapper::connectCcnd()
72{
Alexander Afanasyev3a6c2252012-10-05 16:10:44 -070073 recursive_mutex::scoped_lock lock (m_mutex);
74
Alexander Afanasyev3aaea672012-10-05 15:25:11 -070075 if (m_handle != 0) {
76 ccn_disconnect (m_handle);
77 ccn_destroy (&m_handle);
78 }
79
80 m_handle = ccn_create ();
Zhenkai Zhu26cd6e32012-10-05 13:10:58 -070081 _LOG_DEBUG("<<< connecting to ccnd");
82 if (ccn_connect(m_handle, NULL) < 0)
83 {
Zhenkai Zhu26cd6e32012-10-05 13:10:58 -070084 _LOG_DEBUG("<<< connecting to ccnd failed");
85 BOOST_THROW_EXCEPTION (CcnxOperationException() << errmsg_info_str("connection to ccnd failed"));
86 }
Alexander Afanasyev3a6c2252012-10-05 16:10:44 -070087 m_connected = true;
88
Zhenkai Zhu71bc0ba2012-10-05 14:37:44 -070089 if (!m_registeredInterests.empty())
90 {
91 for (map<std::string, InterestCallback>::const_iterator it = m_registeredInterests.begin(); it != m_registeredInterests.end(); ++it)
92 {
Alexander Afanasyev3aaea672012-10-05 15:25:11 -070093 // clearInterestFilter(it->first);
Zhenkai Zhu71bc0ba2012-10-05 14:37:44 -070094 setInterestFilter(it->first, it->second);
95 _LOG_DEBUG("<<< registering interest filter for: " << it->first);
96 }
97 }
Zhenkai Zhu26cd6e32012-10-05 13:10:58 -070098}
99
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800100CcnxWrapper::~CcnxWrapper()
101{
Alexander Afanasyev1b449c42012-03-13 20:24:07 -0700102 // std::cout << "CcnxWrapper::~CcnxWrapper()" << std::endl;
103 {
104 recursive_mutex::scoped_lock lock(m_mutex);
105 m_running = false;
106 }
107
108 m_thread.join ();
Alexander Afanasyev172d2b72012-03-08 23:43:39 -0800109 ccn_disconnect (m_handle);
Alexander Afanasyev2c180772012-03-13 23:58:46 -0700110 ccn_destroy (&m_handle);
Alexander Afanasyev172d2b72012-03-08 23:43:39 -0800111 ccn_charbuf_destroy (&m_keyLoactor);
112 ccn_keystore_destroy (&m_keyStore);
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800113}
114
Alexander Afanasyev172d2b72012-03-08 23:43:39 -0800115/// @cond include_hidden
116
117void
118CcnxWrapper::createKeyLocator ()
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800119{
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800120 m_keyLoactor = ccn_charbuf_create();
Alexander Afanasyev172d2b72012-03-08 23:43:39 -0800121 ccn_charbuf_append_tt (m_keyLoactor, CCN_DTAG_KeyLocator, CCN_DTAG);
122 ccn_charbuf_append_tt (m_keyLoactor, CCN_DTAG_Key, CCN_DTAG);
123 int res = ccn_append_pubkey_blob (m_keyLoactor, ccn_keystore_public_key(m_keyStore));
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800124 if (res >= 0)
Alexander Afanasyev1285b382012-03-08 16:40:27 -0800125 {
Alexander Afanasyev172d2b72012-03-08 23:43:39 -0800126 ccn_charbuf_append_closer (m_keyLoactor); /* </Key> */
127 ccn_charbuf_append_closer (m_keyLoactor); /* </KeyLocator> */
Alexander Afanasyev1285b382012-03-08 16:40:27 -0800128 }
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800129}
130
Alexander Afanasyev172d2b72012-03-08 23:43:39 -0800131const ccn_pkey*
132CcnxWrapper::getPrivateKey ()
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800133{
Alexander Afanasyev172d2b72012-03-08 23:43:39 -0800134 return ccn_keystore_private_key (m_keyStore);
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800135}
136
Alexander Afanasyev172d2b72012-03-08 23:43:39 -0800137const unsigned char*
138CcnxWrapper::getPublicKeyDigest ()
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800139{
140 return ccn_keystore_public_key_digest(m_keyStore);
141}
142
Alexander Afanasyev172d2b72012-03-08 23:43:39 -0800143ssize_t
144CcnxWrapper::getPublicKeyDigestLength ()
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800145{
146 return ccn_keystore_public_key_digest_length(m_keyStore);
147}
148
Alexander Afanasyev172d2b72012-03-08 23:43:39 -0800149void
150CcnxWrapper::initKeyStore ()
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800151{
Alexander Afanasyev172d2b72012-03-08 23:43:39 -0800152 m_keyStore = ccn_keystore_create ();
Chaoyi Bian95a58c32012-03-09 15:43:59 -0800153 string keyStoreFile = string(getenv("HOME")) + string("/.ccnx/.ccnx_keystore");
154 if (ccn_keystore_init (m_keyStore, (char *)keyStoreFile.c_str(), (char*)"Th1s1sn0t8g00dp8ssw0rd.") < 0)
155 BOOST_THROW_EXCEPTION(CcnxOperationException() << errmsg_info_str(keyStoreFile.c_str()));
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800156}
157
Alexander Afanasyev172d2b72012-03-08 23:43:39 -0800158void
159CcnxWrapper::ccnLoop ()
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800160{
Alexander Afanasyev4f9ea482012-03-15 11:57:29 -0700161 _LOG_FUNCTION (this);
Alexander Afanasyev3a6c2252012-10-05 16:10:44 -0700162 static boost::mt19937 randomGenerator (static_cast<unsigned int> (std::time (0)));
163 static boost::variate_generator<boost::mt19937&, boost::uniform_int<> > rangeUniformRandom (randomGenerator, uniform_int<> (0,1000));
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800164
Alexander Afanasyev3a6c2252012-10-05 16:10:44 -0700165 while (m_running)
166 {
167 try
Alexander Afanasyev2c180772012-03-13 23:58:46 -0700168 {
Zhenkai Zhu26cd6e32012-10-05 13:10:58 -0700169#ifdef _DEBUG_WRAPPER_
170 std::cout << m_c << flush;
171#endif
172 int res = 0;
173 {
174 recursive_mutex::scoped_lock lock (m_mutex);
175 res = ccn_run (m_handle, 0);
176 }
177
178 if (!m_running) break;
179
180 if (res < 0)
181 BOOST_THROW_EXCEPTION (CcnxOperationException()
182 << errmsg_info_str("ccn_run returned error"));
183
184
185 pollfd pfds[1];
186 {
187 recursive_mutex::scoped_lock lock (m_mutex);
188
189 pfds[0].fd = ccn_get_connection_fd (m_handle);
190 pfds[0].events = POLLIN;
191 if (ccn_output_is_pending (m_handle))
192 pfds[0].events |= POLLOUT;
193 }
194
195 int ret = poll (pfds, 1, 1);
196 if (ret < 0)
197 {
198 BOOST_THROW_EXCEPTION (CcnxOperationException() << errmsg_info_str("ccnd socket failed (probably ccnd got stopped)"));
199 }
Alexander Afanasyev1285b382012-03-08 16:40:27 -0800200 }
Alexander Afanasyev3a6c2252012-10-05 16:10:44 -0700201 catch (CcnxOperationException &e)
Zhenkai Zhu26cd6e32012-10-05 13:10:58 -0700202 {
Alexander Afanasyev3a6c2252012-10-05 16:10:44 -0700203 m_connected = false;
204 // probably ccnd has been stopped
Zhenkai Zhu26cd6e32012-10-05 13:10:58 -0700205 // try reconnect with sleep
206 int interval = 1;
207 int maxInterval = 32;
208 while (m_running)
209 {
210 try
211 {
Alexander Afanasyev3a6c2252012-10-05 16:10:44 -0700212 this_thread::sleep (boost::get_system_time () + TIME_SECONDS(interval) + TIME_MILLISECONDS (rangeUniformRandom ()));
213
Zhenkai Zhu26cd6e32012-10-05 13:10:58 -0700214 connectCcnd();
215 _LOG_DEBUG("reconnect to ccnd succeeded");
216 break;
217 }
Alexander Afanasyev3a6c2252012-10-05 16:10:44 -0700218 catch (CcnxOperationException &e)
Zhenkai Zhu26cd6e32012-10-05 13:10:58 -0700219 {
Alexander Afanasyev3a6c2252012-10-05 16:10:44 -0700220 this_thread::sleep (boost::get_system_time () + TIME_SECONDS(interval) + TIME_MILLISECONDS (rangeUniformRandom ()));
221
Zhenkai Zhu26cd6e32012-10-05 13:10:58 -0700222 // do exponential backup for reconnect interval
223 if (interval < maxInterval)
224 {
225 interval *= 2;
226 }
227 }
228 }
229 }
Alexander Afanasyev3a6c2252012-10-05 16:10:44 -0700230 catch (const std::exception &exc)
231 {
232 // catch anything thrown within try block that derives from std::exception
233 std::cerr << exc.what();
234 }
235 catch (...)
236 {
237 cout << "UNKNOWN EXCEPTION !!!" << endl;
238 }
239
Zhenkai Zhu26cd6e32012-10-05 13:10:58 -0700240 }
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800241}
242
Alexander Afanasyev172d2b72012-03-08 23:43:39 -0800243/// @endcond
Zhenkai Zhu1cb29292012-05-31 22:54:34 -0700244int
245CcnxWrapper::publishStringData (const string &name, const string &dataBuffer, int freshness) {
246 publishRawData(name, dataBuffer.c_str(), dataBuffer.length(), freshness);
247}
Alexander Afanasyev172d2b72012-03-08 23:43:39 -0800248
249int
Zhenkai Zhu1cb29292012-05-31 22:54:34 -0700250CcnxWrapper::publishRawData (const string &name, const char *buf, size_t len, int freshness)
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800251{
Zhenkai Zhudc70a292012-06-01 14:00:59 -0700252
Alexander Afanasyev2c180772012-03-13 23:58:46 -0700253 recursive_mutex::scoped_lock lock(m_mutex);
Alexander Afanasyev3a6c2252012-10-05 16:10:44 -0700254 if (!m_running || !m_connected)
Alexander Afanasyev2c180772012-03-13 23:58:46 -0700255 return -1;
256
Alexander Afanasyev45fba082012-03-12 18:05:24 -0700257 // cout << "Publish: " << name << endl;
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800258 ccn_charbuf *pname = ccn_charbuf_create();
259 ccn_charbuf *signed_info = ccn_charbuf_create();
260 ccn_charbuf *content = ccn_charbuf_create();
261
262 ccn_name_from_uri(pname, name.c_str());
263 ccn_signed_info_create(signed_info,
264 getPublicKeyDigest(),
265 getPublicKeyDigestLength(),
266 NULL,
267 CCN_CONTENT_DATA,
268 freshness,
269 NULL,
270 m_keyLoactor);
Zhenkai Zhu009ff792012-03-09 12:37:52 -0800271 if(ccn_encode_ContentObject(content, pname, signed_info,
Zhenkai Zhu1cb29292012-05-31 22:54:34 -0700272 (const unsigned char *)buf, len,
Zhenkai Zhu009ff792012-03-09 12:37:52 -0800273 NULL, getPrivateKey()) < 0)
Zhenkai Zhu26cd6e32012-10-05 13:10:58 -0700274 {
275 // BOOST_THROW_EXCEPTION(CcnxOperationException() << errmsg_info_str("encode content failed"));
276 _LOG_ERROR("<<< Encode content failed " << name);
277 }
Zhenkai Zhu009ff792012-03-09 12:37:52 -0800278
Zhenkai Zhu009ff792012-03-09 12:37:52 -0800279 if (ccn_put(m_handle, content->buf, content->length) < 0)
Zhenkai Zhu26cd6e32012-10-05 13:10:58 -0700280 {
281 // BOOST_THROW_EXCEPTION(CcnxOperationException() << errmsg_info_str("ccnput failed"));
282 _LOG_ERROR("<<< ccnput content failed " << name);
283 }
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800284
Alexander Afanasyev172d2b72012-03-08 23:43:39 -0800285 ccn_charbuf_destroy (&pname);
286 ccn_charbuf_destroy (&signed_info);
287 ccn_charbuf_destroy (&content);
Alexander Afanasyev2c180772012-03-13 23:58:46 -0700288 return 0;
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800289}
290
291
Alexander Afanasyev172d2b72012-03-08 23:43:39 -0800292static ccn_upcall_res
293incomingInterest(ccn_closure *selfp,
294 ccn_upcall_kind kind,
295 ccn_upcall_info *info)
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800296{
Alexander Afanasyev172d2b72012-03-08 23:43:39 -0800297 CcnxWrapper::InterestCallback *f = static_cast<CcnxWrapper::InterestCallback*> (selfp->data);
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800298
299 switch (kind)
Alexander Afanasyev1285b382012-03-08 16:40:27 -0800300 {
Zhenkai Zhucd747592012-03-09 12:08:17 -0800301 case CCN_UPCALL_FINAL: // effective in unit tests
Alexander Afanasyev172d2b72012-03-08 23:43:39 -0800302 delete f;
Chaoyi Bian11f294f2012-03-08 14:28:06 -0800303 delete selfp;
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800304 return CCN_UPCALL_RESULT_OK;
305
306 case CCN_UPCALL_INTEREST:
307 break;
308
309 default:
310 return CCN_UPCALL_RESULT_OK;
Alexander Afanasyev1285b382012-03-08 16:40:27 -0800311 }
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800312
Chaoyi Bian93d43102012-03-07 14:28:56 -0800313 string interest;
Chaoyi Bian02dba3c2012-03-07 21:45:22 -0800314 for (int i = 0; i < info->interest_comps->n - 1; i++)
Alexander Afanasyev1285b382012-03-08 16:40:27 -0800315 {
316 char *comp;
317 size_t size;
318 interest += "/";
319 ccn_name_comp_get(info->interest_ccnb, info->interest_comps, i, (const unsigned char **)&comp, &size);
Chaoyi Bian95a58c32012-03-09 15:43:59 -0800320 string compStr(comp, size);
321 interest += compStr;
Alexander Afanasyev1285b382012-03-08 16:40:27 -0800322 }
Alexander Afanasyev172d2b72012-03-08 23:43:39 -0800323 (*f) (interest);
Zhenkai Zhu71bc0ba2012-10-05 14:37:44 -0700324 _LOG_DEBUG("<<< processed interest: " << interest);
Chaoyi Bian93d43102012-03-07 14:28:56 -0800325 return CCN_UPCALL_RESULT_OK;
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800326}
327
Alexander Afanasyev172d2b72012-03-08 23:43:39 -0800328static ccn_upcall_res
329incomingData(ccn_closure *selfp,
330 ccn_upcall_kind kind,
331 ccn_upcall_info *info)
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800332{
Zhenkai Zhu80af0e02012-05-31 15:49:07 -0700333 ClosurePass *cp = static_cast<ClosurePass *> (selfp->data);
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800334
335 switch (kind)
Alexander Afanasyev1285b382012-03-08 16:40:27 -0800336 {
Zhenkai Zhucd747592012-03-09 12:08:17 -0800337 case CCN_UPCALL_FINAL: // effecitve in unit tests
Zhenkai Zhu80af0e02012-05-31 15:49:07 -0700338 delete cp;
339 cp = NULL;
Chaoyi Bian11f294f2012-03-08 14:28:06 -0800340 delete selfp;
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800341 return CCN_UPCALL_RESULT_OK;
342
343 case CCN_UPCALL_CONTENT:
344 break;
345
Zhenkai Zhu80af0e02012-05-31 15:49:07 -0700346 case CCN_UPCALL_INTEREST_TIMED_OUT: {
347 if (cp != NULL && cp->getRetry() > 0) {
348 cp->decRetry();
349 return CCN_UPCALL_RESULT_REEXPRESS;
350 }
351 return CCN_UPCALL_RESULT_OK;
352 }
353
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800354 default:
355 return CCN_UPCALL_RESULT_OK;
Alexander Afanasyev1285b382012-03-08 16:40:27 -0800356 }
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800357
358 char *pcontent;
359 size_t len;
Zhenkai Zhu009ff792012-03-09 12:37:52 -0800360 if (ccn_content_get_value(info->content_ccnb, info->pco->offset[CCN_PCO_E], info->pco, (const unsigned char **)&pcontent, &len) < 0)
Zhenkai Zhu26cd6e32012-10-05 13:10:58 -0700361 {
362 // BOOST_THROW_EXCEPTION(CcnxOperationException() << errmsg_info_str("decode ContentObject failed"));
363 _LOG_ERROR("<<< Decode content failed ");
364 }
Zhenkai Zhu009ff792012-03-09 12:37:52 -0800365
Chaoyi Bian4194b742012-03-08 17:21:35 -0800366 string name;
367 for (int i = 0; i < info->content_comps->n - 1; i++)
368 {
369 char *comp;
370 size_t size;
371 name += "/";
372 ccn_name_comp_get(info->content_ccnb, info->content_comps, i, (const unsigned char **)&comp, &size);
Chaoyi Bian95a58c32012-03-09 15:43:59 -0800373 string compStr(comp, size);
374 name += compStr;
Chaoyi Bian4194b742012-03-08 17:21:35 -0800375 }
Zhenkai Zhu80af0e02012-05-31 15:49:07 -0700376
377 cp->runCallback(name, pcontent, len);
378
Chaoyi Bian11f294f2012-03-08 14:28:06 -0800379 return CCN_UPCALL_RESULT_OK;
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800380}
381
Zhenkai Zhu1cb29292012-05-31 22:54:34 -0700382int CcnxWrapper::sendInterestForString (const string &strInterest, const StringDataCallback &strDataCallback, int retry)
Zhenkai Zhu80af0e02012-05-31 15:49:07 -0700383{
Zhenkai Zhu1cb29292012-05-31 22:54:34 -0700384 DataClosurePass * pass = new DataClosurePass(STRING_FORM, retry, strDataCallback);
Zhenkai Zhu80af0e02012-05-31 15:49:07 -0700385 sendInterest(strInterest, pass);
386}
387
Zhenkai Zhu1cb29292012-05-31 22:54:34 -0700388int CcnxWrapper::sendInterest (const string &strInterest, const RawDataCallback &rawDataCallback, int retry)
Zhenkai Zhu80af0e02012-05-31 15:49:07 -0700389{
390 RawDataClosurePass * pass = new RawDataClosurePass(RAW_DATA, retry, rawDataCallback);
391 sendInterest(strInterest, pass);
392}
393
394int CcnxWrapper::sendInterest (const string &strInterest, void *dataPass)
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800395{
Alexander Afanasyev2c180772012-03-13 23:58:46 -0700396 recursive_mutex::scoped_lock lock(m_mutex);
Alexander Afanasyev3a6c2252012-10-05 16:10:44 -0700397 if (!m_running || !m_connected)
Alexander Afanasyev2c180772012-03-13 23:58:46 -0700398 return -1;
399
Alexander Afanasyev1b449c42012-03-13 20:24:07 -0700400 // std::cout << "Send interests for " << strInterest << std::endl;
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800401 ccn_charbuf *pname = ccn_charbuf_create();
402 ccn_closure *dataClosure = new ccn_closure;
Chaoyi Bian95a58c32012-03-09 15:43:59 -0800403
Alexander Afanasyev172d2b72012-03-08 23:43:39 -0800404 ccn_name_from_uri (pname, strInterest.c_str());
Zhenkai Zhu80af0e02012-05-31 15:49:07 -0700405 dataClosure->data = dataPass;
Chaoyi Bian95a58c32012-03-09 15:43:59 -0800406
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800407 dataClosure->p = &incomingData;
Zhenkai Zhu009ff792012-03-09 12:37:52 -0800408 if (ccn_express_interest (m_handle, pname, dataClosure, NULL) < 0)
Zhenkai Zhu26cd6e32012-10-05 13:10:58 -0700409 {
410 // BOOST_THROW_EXCEPTION(CcnxOperationException() << errmsg_info_str("express interest failed"));
411 _LOG_ERROR("<<< Express interest failed: " << strInterest);
412 }
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800413
Zhenkai Zhu71bc0ba2012-10-05 14:37:44 -0700414 _LOG_DEBUG("<<< Sending interest: " << strInterest);
415
Alexander Afanasyev172d2b72012-03-08 23:43:39 -0800416 ccn_charbuf_destroy (&pname);
Alexander Afanasyev2c180772012-03-13 23:58:46 -0700417 return 0;
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800418}
419
Alexander Afanasyev172d2b72012-03-08 23:43:39 -0800420int CcnxWrapper::setInterestFilter (const string &prefix, const InterestCallback &interestCallback)
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800421{
Alexander Afanasyev2c180772012-03-13 23:58:46 -0700422 recursive_mutex::scoped_lock lock(m_mutex);
Alexander Afanasyev3a6c2252012-10-05 16:10:44 -0700423 if (!m_running || !m_connected)
Alexander Afanasyev2c180772012-03-13 23:58:46 -0700424 return -1;
425
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800426 ccn_charbuf *pname = ccn_charbuf_create();
427 ccn_closure *interestClosure = new ccn_closure;
428
Alexander Afanasyev172d2b72012-03-08 23:43:39 -0800429 ccn_name_from_uri (pname, prefix.c_str());
430 interestClosure->data = new InterestCallback (interestCallback); // should be removed when closure is removed
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800431 interestClosure->p = &incomingInterest;
Alexander Afanasyev387ac952012-03-11 23:49:27 -0700432 int ret = ccn_set_interest_filter (m_handle, pname, interestClosure);
433 if (ret < 0)
434 {
435 BOOST_THROW_EXCEPTION(CcnxOperationException() << errmsg_info_str("set interest filter failed") << errmsg_info_int (ret));
436 }
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800437
Zhenkai Zhu71bc0ba2012-10-05 14:37:44 -0700438 m_registeredInterests.insert(pair<std::string, InterestCallback>(prefix, interestCallback));
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800439 ccn_charbuf_destroy(&pname);
440}
441
Alexander Afanasyev1b449c42012-03-13 20:24:07 -0700442void
443CcnxWrapper::clearInterestFilter (const std::string &prefix)
444{
Alexander Afanasyev2c180772012-03-13 23:58:46 -0700445 recursive_mutex::scoped_lock lock(m_mutex);
Alexander Afanasyev3a6c2252012-10-05 16:10:44 -0700446 if (!m_running || !m_connected)
Alexander Afanasyev2c180772012-03-13 23:58:46 -0700447 return;
448
Alexander Afanasyev1b449c42012-03-13 20:24:07 -0700449 std::cout << "clearInterestFilter" << std::endl;
450 ccn_charbuf *pname = ccn_charbuf_create();
451
452 ccn_name_from_uri (pname, prefix.c_str());
453 int ret = ccn_set_interest_filter (m_handle, pname, 0);
454 if (ret < 0)
455 {
456 BOOST_THROW_EXCEPTION(CcnxOperationException() << errmsg_info_str("set interest filter failed") << errmsg_info_int (ret));
457 }
458
Zhenkai Zhu71bc0ba2012-10-05 14:37:44 -0700459 m_registeredInterests.erase(prefix);
Alexander Afanasyev1b449c42012-03-13 20:24:07 -0700460 ccn_charbuf_destroy(&pname);
461}
462
Alexander Afanasyev50f7e9f2012-10-08 00:20:42 -0700463string
464CcnxWrapper::getLocalPrefix ()
465{
Alexander Afanasyev7f680292012-10-08 14:30:42 -0700466 struct ccn * tmp_handle = ccn_create ();
467 int res = ccn_connect (tmp_handle, NULL);
468 if (res < 0)
469 {
470 _LOG_ERROR ("connecting to ccnd failed");
471 return "";
472 }
473
Alexander Afanasyev50f7e9f2012-10-08 00:20:42 -0700474 string retval = "";
475
476 struct ccn_charbuf *templ = ccn_charbuf_create();
477 ccn_charbuf_append_tt(templ, CCN_DTAG_Interest, CCN_DTAG);
478 ccn_charbuf_append_tt(templ, CCN_DTAG_Name, CCN_DTAG);
479 ccn_charbuf_append_closer(templ); /* </Name> */
480 // XXX - use pubid if possible
481 ccn_charbuf_append_tt(templ, CCN_DTAG_MaxSuffixComponents, CCN_DTAG);
482 ccnb_append_number(templ, 1);
483 ccn_charbuf_append_closer(templ); /* </MaxSuffixComponents> */
484 ccnb_tagged_putf(templ, CCN_DTAG_Scope, "%d", 2);
485 ccn_charbuf_append_closer(templ); /* </Interest> */
486
487 struct ccn_charbuf *name = ccn_charbuf_create ();
Alexander Afanasyev7f680292012-10-08 14:30:42 -0700488 res = ccn_name_from_uri (name, "/local/ndn/prefix");
Alexander Afanasyev50f7e9f2012-10-08 00:20:42 -0700489 if (res < 0) {
490 _LOG_ERROR ("Something wrong with `ccn_name_from_uri` call");
491 }
492 else
493 {
Alexander Afanasyev7f680292012-10-08 14:30:42 -0700494 struct ccn_fetch *fetch = ccn_fetch_new (tmp_handle);
Alexander Afanasyevcf301962012-10-08 13:25:35 -0700495
Alexander Afanasyev7f680292012-10-08 14:30:42 -0700496 struct ccn_fetch_stream *stream = ccn_fetch_open (fetch, name, "/local/ndn/prefix",
497 NULL, 4, CCN_V_HIGHEST, 0);
Alexander Afanasyev50f7e9f2012-10-08 00:20:42 -0700498 if (stream == NULL) {
499 _LOG_ERROR ("Cannot create ccn_fetch_stream");
500 }
501 else
502 {
503 ostringstream os;
Alexander Afanasyev7f680292012-10-08 14:30:42 -0700504
505 int counter = 0;
Alexander Afanasyev50f7e9f2012-10-08 00:20:42 -0700506 char buf[256];
Alexander Afanasyevcf301962012-10-08 13:25:35 -0700507 while (true) {
Alexander Afanasyevcf301962012-10-08 13:25:35 -0700508 res = ccn_fetch_read (stream, buf, sizeof(buf));
Alexander Afanasyevcf301962012-10-08 13:25:35 -0700509
510 if (res == 0) {
511 break;
512 }
513
Alexander Afanasyev50f7e9f2012-10-08 00:20:42 -0700514 if (res > 0) {
515 os << string(buf, res);
516 } else if (res == CCN_FETCH_READ_NONE) {
Alexander Afanasyev7f680292012-10-08 14:30:42 -0700517 if (counter < 2)
518 {
519 ccn_run(tmp_handle, 1000);
520 counter ++;
521 }
522 else
523 {
524 break;
525 }
Alexander Afanasyev50f7e9f2012-10-08 00:20:42 -0700526 } else if (res == CCN_FETCH_READ_END) {
527 break;
528 } else if (res == CCN_FETCH_READ_TIMEOUT) {
529 break;
530 } else {
531 _LOG_ERROR ("fatal error. should be reported");
532 break;
533 }
534 }
535 retval = os.str ();
536 stream = ccn_fetch_close(stream);
537 }
538 fetch = ccn_fetch_destroy(fetch);
539 }
540
541 ccn_charbuf_destroy (&name);
542
Alexander Afanasyev7f680292012-10-08 14:30:42 -0700543 ccn_disconnect (tmp_handle);
544 ccn_destroy (&tmp_handle);
545
Alexander Afanasyev50f7e9f2012-10-08 00:20:42 -0700546 return retval;
547}
548
549
550
551
552
Zhenkai Zhu1cb29292012-05-31 22:54:34 -0700553DataClosurePass::DataClosurePass (CallbackType type, int retry, const CcnxWrapper::StringDataCallback &strDataCallback): ClosurePass(type, retry), m_callback(NULL)
Zhenkai Zhu80af0e02012-05-31 15:49:07 -0700554{
Zhenkai Zhu1cb29292012-05-31 22:54:34 -0700555 m_callback = new CcnxWrapper::StringDataCallback (strDataCallback);
Zhenkai Zhu80af0e02012-05-31 15:49:07 -0700556}
557
558DataClosurePass::~DataClosurePass ()
559{
560 delete m_callback;
561 m_callback = NULL;
562}
563
564void
565DataClosurePass::runCallback(std::string name, const char *data, size_t len)
566{
567 string content(data, len);
568 if (m_callback != NULL) {
569 (*m_callback)(name, content);
570 }
571}
572
573
574RawDataClosurePass::RawDataClosurePass (CallbackType type, int retry, const CcnxWrapper::RawDataCallback &rawDataCallback): ClosurePass(type, retry), m_callback(NULL)
575{
576 m_callback = new CcnxWrapper::RawDataCallback (rawDataCallback);
577}
578
579RawDataClosurePass::~RawDataClosurePass ()
580{
581 delete m_callback;
582 m_callback = NULL;
583}
584
585void
586RawDataClosurePass::runCallback(std::string name, const char *data, size_t len)
587{
588 if (m_callback != NULL) {
589 (*m_callback)(name, data, len);
590 }
591}
592
Chaoyi Bian3e6e5142012-03-06 22:32:19 -0800593}