Now code compiles and seem to have all the features... Though most likely not yet working
diff --git a/ccnx/sync-scheduler.cc b/ccnx/sync-scheduler.cc
index 4ec13de..866f742 100644
--- a/ccnx/sync-scheduler.cc
+++ b/ccnx/sync-scheduler.cc
@@ -108,7 +108,7 @@
}
void
-Scheduler::schedule (const boost::posix_time::time_duration &reltime, Event event, uint32_t label)
+Scheduler::schedule (const TimeDuration &reltime, Event event, uint32_t label)
{
{
lock_guard<mutex> lock (m_eventsMutex);
diff --git a/ccnx/sync-scheduler.h b/ccnx/sync-scheduler.h
index 53b40af..c7ebe09 100644
--- a/ccnx/sync-scheduler.h
+++ b/ccnx/sync-scheduler.h
@@ -28,6 +28,9 @@
#include "sync-logic-event-container.h"
+#define TIME_SECONDS(number) boost::posix_time::seconds (number)
+typedef boost::posix_time::time_duration TimeDuration;
+
namespace Sync {
/**
@@ -55,7 +58,7 @@
* @param label Label for the event
*/
void
- schedule (const boost::posix_time::time_duration &reltime, Event event, uint32_t label);
+ schedule (const TimeDuration &reltime, Event event, uint32_t label);
/**
* @brief Cancel all events for the label
diff --git a/model/sync-interest-table.cc b/model/sync-interest-table.cc
index 7b9ed35..a9ed265 100644
--- a/model/sync-interest-table.cc
+++ b/model/sync-interest-table.cc
@@ -32,7 +32,7 @@
SyncInterestTable::SyncInterestTable ()
{
- m_scheduler.schedule (posix_time::seconds (4),
+ m_scheduler.schedule (TIME_SECONDS (4),
bind (&SyncInterestTable::expireInterests, this),
0);
}
@@ -113,7 +113,7 @@
_LOG_DEBUG ("expireInterests (): expired " << count);
- m_scheduler.schedule (posix_time::seconds (4),
+ m_scheduler.schedule (TIME_SECONDS (4),
bind (&SyncInterestTable::expireInterests, this),
0);
}
diff --git a/model/sync-logic.cc b/model/sync-logic.cc
index 773f368..17a0935 100644
--- a/model/sync-logic.cc
+++ b/model/sync-logic.cc
@@ -65,7 +65,7 @@
m_ccnxHandle->setInterestFilter (m_syncPrefix,
bind (&SyncLogic::respondSyncInterest, this, _1));
- m_scheduler.schedule (posix_time::seconds (0),
+ m_scheduler.schedule (TIME_SECONDS (0),
bind (&SyncLogic::sendSyncInterest, this),
REEXPRESSING_INTEREST);
}
@@ -117,7 +117,7 @@
m_syncResponseFreshness);
if (m_outstandingInterest == interestName)
{
- m_scheduler.schedule (posix_time::seconds (0),
+ m_scheduler.schedule (TIME_SECONDS (0),
bind (&SyncLogic::sendSyncInterest, this),
REEXPRESSING_INTEREST);
}
@@ -163,7 +163,7 @@
m_syncResponseFreshness);
if (m_outstandingInterest == interestName)
{
- m_scheduler.schedule (posix_time::seconds (0),
+ m_scheduler.schedule (TIME_SECONDS (0),
bind (&SyncLogic::sendSyncInterest, this),
REEXPRESSING_INTEREST);
}
@@ -172,7 +172,7 @@
if (!timedProcessing)
{
- m_scheduler.schedule (posix_time::milliseconds (m_rangeUniformRandom ()) /*from 20 to 100ms*/,
+ m_scheduler.schedule (TIME_MILLISECONDS (m_rangeUniformRandom ()) /*from 20 to 100ms*/,
bind (&SyncLogic::processSyncInterest, this, digest, interestName, true),
DELAYED_INTEREST_PROCESSING);
@@ -188,7 +188,7 @@
if (m_outstandingInterest == interestName)
{
- m_scheduler.schedule (posix_time::seconds (0),
+ m_scheduler.schedule (TIME_SECONDS (0),
bind (&SyncLogic::sendSyncInterest, this),
REEXPRESSING_INTEREST);
}
@@ -280,7 +280,7 @@
// if state has changed, then it is safe to express a new interest
if (diffLog->getLeaves ().size () > 0)
{
- m_scheduler.schedule (posix_time::seconds (0),
+ m_scheduler.schedule (TIME_SECONDS (0),
bind (&SyncLogic::sendSyncInterest, this),
REEXPRESSING_INTEREST);
}
@@ -290,7 +290,7 @@
// Otherwise we will get immediate reply from the local daemon and there will be 100% utilization
m_scheduler.cancel (REEXPRESSING_INTEREST);
// m_scheduler.schedule (posix_time::seconds (0),
- m_scheduler.schedule (posix_time::seconds (m_syncResponseFreshness) + posix_time::milliseconds (1),
+ m_scheduler.schedule (TIME_SECONDS (m_syncResponseFreshness) + TIME_MILLISECONDS (1),
bind (&SyncLogic::sendSyncInterest, this),
REEXPRESSING_INTEREST);
}
@@ -322,7 +322,7 @@
{
_LOG_DEBUG ("Have satisfied our own interest. Scheduling interest reexpression");
// we need to reexpress interest only if we satisfied our own interest
- m_scheduler.schedule (posix_time::milliseconds (0),
+ m_scheduler.schedule (TIME_SECONDS (0),
bind (&SyncLogic::sendSyncInterest, this),
REEXPRESSING_INTEREST);
}
@@ -405,9 +405,25 @@
bind (&SyncLogic::processSyncData, this, _1, _2));
m_scheduler.cancel (REEXPRESSING_INTEREST);
- m_scheduler.schedule (posix_time::seconds (4),
+ m_scheduler.schedule (TIME_SECONDS (4),
bind (&SyncLogic::sendSyncInterest, this),
REEXPRESSING_INTEREST);
}
+#ifdef NS3_MODULE
+void
+SyncLogic::StartApplication ()
+{
+ m_ccnxHandle->SetNode (GetNode ());
+ m_ccnxHandle->StartApplication ();
+}
+
+void
+SyncLogic::StopApplication ()
+{
+ m_ccnxHandle->StopApplication ();
+}
+#endif
+
+
}
diff --git a/model/sync-logic.h b/model/sync-logic.h
index ad0a208..64d551b 100644
--- a/model/sync-logic.h
+++ b/model/sync-logic.h
@@ -43,6 +43,10 @@
#endif
#endif
+#ifdef NS3_MODULE
+#include <ns3/application.h>
+#endif
+
namespace Sync {
/**
@@ -51,6 +55,9 @@
* interests and data)
*/
class SyncLogic
+#ifdef NS3_MODULE
+ : public ns3::Application
+#endif
{
public:
typedef boost::function< void ( const std::string &/*prefix*/, const SeqNo &/*newSeq*/, const SeqNo &/*oldSeq*/ ) > LogicUpdateCallback;
@@ -98,6 +105,12 @@
Scheduler &
getScheduler () { return m_scheduler; }
#endif
+
+protected:
+#ifdef NS3_MODULE
+ virtual void StartApplication ();
+ virtual void StopApplication ();
+#endif
private:
void
diff --git a/ns3/sync-ccnx-wrapper.cc b/ns3/sync-ccnx-wrapper.cc
new file mode 100644
index 0000000..e66bda1
--- /dev/null
+++ b/ns3/sync-ccnx-wrapper.cc
@@ -0,0 +1,255 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2012 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ * Chaoyi Bian <bcy@pku.edu.cn>
+ * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#include "sync-ccnx-wrapper.h"
+#include "sync-log.h"
+#include <boost/throw_exception.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/lambda/lambda.hpp>
+#include <boost/lambda/bind.hpp>
+
+namespace ll = boost::lambda;
+
+#include <ns3/ccnx-name-components.h>
+#include <ns3/ccnx-interest-header.h>
+#include <ns3/ccnx-content-object-header.h>
+#include <ns3/ccnx-face.h>
+#include <ns3/packet.h>
+#include <ns3/ccnx-fib.h>
+
+typedef boost::error_info<struct tag_errmsg, std::string> errmsg_info_str;
+typedef boost::error_info<struct tag_errmsg, int> errmsg_info_int;
+
+using namespace std;
+using namespace boost;
+using namespace ns3;
+
+INIT_LOGGER ("CcnxWrapper");
+
+namespace Sync {
+
+CcnxWrapper::CcnxWrapper()
+{
+}
+
+CcnxWrapper::~CcnxWrapper()
+{
+}
+
+void
+CcnxWrapper::StartApplication ()
+{
+ CcnxApp::StartApplication ();
+}
+
+void
+CcnxWrapper::StopApplication ()
+{
+ CcnxApp::StopApplication ();
+}
+
+int
+CcnxWrapper::publishData (const string &dataName, const string &dataBuffer, int freshness)
+{
+ // NS_LOG_INFO ("Requesting Interest: \n" << interestHeader);
+ _LOG_INFO ("> Data for " << dataName);
+
+ Ptr<CcnxNameComponents> name = Create<CcnxNameComponents> ();
+ istringstream is (dataName);
+ is >> *name;
+
+ static CcnxContentObjectTail trailer;
+
+ CcnxContentObjectHeader data;
+ data.SetName (name);
+ data.SetFreshness (Seconds (freshness));
+
+ Ptr<Packet> packet = Create<Packet> (reinterpret_cast<const uint8_t*> (dataBuffer.c_str ()), dataBuffer.size ());
+
+ packet->AddHeader (data);
+ packet->AddTrailer (trailer);
+
+ m_protocolHandler (packet);
+
+ m_transmittedContentObjects (&data, packet, this, m_face);
+
+ return 0;
+}
+
+int CcnxWrapper::sendInterest (const string &strInterest, const DataCallback &dataCallback)
+{
+ // NS_LOG_INFO ("Requesting Interest: \n" << interestHeader);
+ _LOG_INFO ("> Interest for " << strInterest);
+
+ Ptr<CcnxNameComponents> name = Create<CcnxNameComponents> ();
+ istringstream is (strInterest);
+ is >> *name;
+
+ CcnxInterestHeader interestHeader;
+ interestHeader.SetNonce (m_rand.GetValue ());
+ interestHeader.SetName (name);
+ interestHeader.SetInterestLifetime (Seconds (4.0));
+
+ Ptr<Packet> packet = Create<Packet> ();
+ packet->AddHeader (interestHeader);
+
+ m_protocolHandler (packet);
+
+ m_transmittedInterests (&interestHeader, this, m_face);
+
+ // Record the callback
+ CcnxFilterEntryContainer<DataCallback>::type::iterator entry = m_dataCallbacks.find (*name);
+ if (entry == m_dataCallbacks.end ())
+ {
+ pair<CcnxFilterEntryContainer<DataCallback>::type::iterator, bool> status =
+ m_dataCallbacks.insert (CcnxFilterEntry<DataCallback> (name));
+
+ entry = status.first;
+ }
+ m_dataCallbacks.modify (entry, ll::bind (&CcnxFilterEntry<DataCallback>::AddCallback, ll::_1, dataCallback));
+
+ return 0;
+}
+
+int CcnxWrapper::setInterestFilter (const string &prefix, const InterestCallback &interestCallback)
+{
+ Ptr<CcnxNameComponents> name = Create<CcnxNameComponents> ();
+ istringstream is (prefix);
+ is >> *name;
+
+ CcnxFilterEntryContainer<InterestCallback>::type::iterator entry = m_interestCallbacks.find (*name);
+ if (entry == m_interestCallbacks.end ())
+ {
+ pair<CcnxFilterEntryContainer<InterestCallback>::type::iterator, bool> status =
+ m_interestCallbacks.insert (CcnxFilterEntry<InterestCallback> (name));
+
+ entry = status.first;
+ }
+
+ m_interestCallbacks.modify (entry, ll::bind (&CcnxFilterEntry<InterestCallback>::AddCallback, ll::_1, interestCallback));
+
+ // creating actual face
+
+ Ptr<CcnxFib> fib = GetNode ()->GetObject<CcnxFib> ();
+ CcnxFibEntryContainer::type::iterator fibEntry = fib->Add (*name, m_face, 0);
+
+ // make face green, so it will be used primarily
+ fib->m_fib.modify (fibEntry,
+ ll::bind (&CcnxFibEntry::UpdateStatus,
+ ll::_1, m_face, CcnxFibFaceMetric::NDN_FIB_GREEN));
+
+ return 0;
+}
+
+void
+CcnxWrapper::clearInterestFilter (const std::string &prefix)
+{
+ Ptr<CcnxNameComponents> name = Create<CcnxNameComponents> ();
+ istringstream is (prefix);
+ is >> *name;
+
+ CcnxFilterEntryContainer<InterestCallback>::type::iterator entry = m_interestCallbacks.find (*name);
+ if (entry == m_interestCallbacks.end ())
+ return;
+
+ m_interestCallbacks.modify (entry, ll::bind (&CcnxFilterEntry<InterestCallback>::ClearCallback, ll::_1));
+}
+
+CcnxFilterEntryContainer<CcnxWrapper::InterestCallback>::type::iterator
+CcnxWrapper::InterestCallbackLookup (const ns3::CcnxNameComponents &name)
+{
+ CcnxFilterEntryContainer<InterestCallback>::type::iterator entry = m_interestCallbacks.end ();
+
+ // do the longest prefix match
+ for (size_t componentsCount = name.GetComponents ().size ()+1;
+ componentsCount > 0;
+ componentsCount--)
+ {
+ CcnxNameComponents subPrefix (name.GetSubComponents (componentsCount-1));
+
+ entry = m_interestCallbacks.find (subPrefix);
+ if (entry != m_interestCallbacks.end())
+ return entry;
+ }
+
+ return entry;
+}
+
+CcnxFilterEntryContainer<CcnxWrapper::DataCallback>::type::iterator
+CcnxWrapper::DataCallbackLookup (const ns3::CcnxNameComponents &name)
+{
+ CcnxFilterEntryContainer<DataCallback>::type::iterator entry = m_dataCallbacks.end ();
+
+ // do the longest prefix match
+ for (size_t componentsCount = name.GetComponents ().size ()+1;
+ componentsCount > 0;
+ componentsCount--)
+ {
+ CcnxNameComponents subPrefix (name.GetSubComponents (componentsCount-1));
+
+ entry = m_dataCallbacks.find (subPrefix);
+ if (entry != m_dataCallbacks.end())
+ return entry;
+ }
+
+ return entry;
+}
+
+void
+CcnxWrapper::OnInterest (const Ptr<const CcnxInterestHeader> &interest, Ptr<Packet> packet)
+{
+ CcnxApp::OnInterest (interest, packet);
+
+ CcnxFilterEntryContainer<InterestCallback>::type::iterator entry = InterestCallbackLookup (interest->GetName ());
+ if (entry == m_interestCallbacks.end ())
+ {
+ _LOG_DEBUG ("No Interest callback set");
+ return;
+ }
+
+ entry->m_callback (lexical_cast<string> (interest->GetName ()));
+}
+
+void
+CcnxWrapper::OnContentObject (const Ptr<const CcnxContentObjectHeader> &contentObject,
+ Ptr<Packet> payload)
+{
+ CcnxApp::OnContentObject (contentObject, payload);
+
+ CcnxFilterEntryContainer<DataCallback>::type::iterator entry = DataCallbackLookup (contentObject->GetName ());
+ if (entry == m_dataCallbacks.end ())
+ {
+ _LOG_DEBUG ("No Data callback set");
+ return;
+ }
+
+ ostringstream content;
+ payload->CopyData (&content, payload->GetSize ());
+
+ entry->m_callback (lexical_cast<string> (contentObject->GetName ()), content.str ());
+
+ // i guess it make sense to remove callback when interest is satisfied
+ m_dataCallbacks.erase (entry);
+}
+
+
+}
diff --git a/ns3/sync-ccnx-wrapper.h b/ns3/sync-ccnx-wrapper.h
new file mode 100644
index 0000000..5776c1a
--- /dev/null
+++ b/ns3/sync-ccnx-wrapper.h
@@ -0,0 +1,195 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2012 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ * Chaoyi Bian <bcy@pku.edu.cn>
+ * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#ifndef SYNC_CCNX_WRAPPER_H
+#define SYNC_CCNX_WRAPPER_H
+
+#include <boost/exception/all.hpp>
+#include <boost/function.hpp>
+#include <string>
+
+#include <ns3/ptr.h>
+#include <ns3/node.h>
+#include <ns3/random-variable.h>
+#include <ns3/ccnx-app.h>
+#include <ns3/ccnx-name-components.h>
+#include <ns3/hash-helper.h>
+
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/hashed_index.hpp>
+#include <boost/multi_index/mem_fun.hpp>
+
+/**
+ * \defgroup sync SYNC protocol
+ *
+ * Implementation of SYNC protocol
+ */
+namespace Sync {
+
+template<class Callback>
+struct CcnxFilterEntry
+{
+public:
+ CcnxFilterEntry (ns3::Ptr<const ns3::CcnxNameComponents> prefix)
+ : m_prefix (prefix)
+ { }
+
+ const ns3::CcnxNameComponents &
+ GetPrefix () const
+ { return *m_prefix; }
+
+ void
+ AddCallback (Callback callback)
+ {
+ m_callback = callback;
+ }
+
+ void
+ ClearCallback ()
+ {
+ m_callback = 0;
+ }
+
+public:
+ ns3::Ptr<const ns3::CcnxNameComponents> m_prefix; ///< \brief Prefix of the PIT entry
+ Callback m_callback;
+};
+
+
+template<class Callback>
+struct CcnxFilterEntryContainer
+{
+ typedef
+ boost::multi_index::multi_index_container<
+ CcnxFilterEntry<Callback>,
+ boost::multi_index::indexed_by<
+ // indexed by hash
+ boost::multi_index::hashed_unique<
+ boost::multi_index::const_mem_fun< CcnxFilterEntry<Callback>, const ns3::CcnxNameComponents&, &CcnxFilterEntry<Callback>::GetPrefix >,
+ ns3::CcnxPrefixHash
+ >
+ >
+ > type;
+};
+
+
+
+struct CcnxOperationException : virtual boost::exception, virtual std::exception { };
+/**
+ * \ingroup sync
+ * @brief A wrapper for ccnx library; clients of this code do not need to deal
+ * with ccnx library
+ */
+class CcnxWrapper
+ : public ns3::CcnxApp
+{
+public:
+ typedef boost::function<void (std::string, std::string)> DataCallback;
+ typedef boost::function<void (std::string)> InterestCallback;
+
+ /**
+ * @brief initialize the wrapper; a lot of things needs to be done. 1) init
+ * keystore 2) init keylocator 3) start a thread to hold a loop of ccn_run
+ *
+ */
+ CcnxWrapper();
+ ~CcnxWrapper();
+
+ // from CcnxApp
+ /**
+ * @brief Should be called after Node pointer is set to create face and start application
+ */
+ virtual void
+ StartApplication ();
+
+ /**
+ * @brief Stop application
+ */
+ virtual void
+ StopApplication ();
+
+ /**
+ * @brief send Interest; need to grab lock m_mutex first
+ *
+ * @param strInterest the Interest name
+ * @param dataCallback the callback function to deal with the returned data
+ * @return the return code of ccn_express_interest
+ */
+ int
+ sendInterest (const std::string &strInterest, const DataCallback &dataCallback);
+
+ /**
+ * @brief set Interest filter (specify what interest you want to receive)
+ *
+ * @param prefix the prefix of Interest
+ * @param interestCallback the callback function to deal with the returned data
+ * @return the return code of ccn_set_interest_filter
+ */
+ int
+ setInterestFilter (const std::string &prefix, const InterestCallback &interestCallback);
+
+ /**
+ * @brief clear Interest filter
+ * @param prefix the prefix of Interest
+ */
+ void
+ clearInterestFilter (const std::string &prefix);
+
+ /**
+ * @brief publish data and put it to local ccn content store; need to grab
+ * lock m_mutex first
+ *
+ * @param name the name for the data object
+ * @param dataBuffer the data to be published
+ * @param freshness the freshness time for the data object
+ * @return code generated by ccnx library calls, >0 if success
+ */
+ int
+ publishData (const std::string &name, const std::string &dataBuffer, int freshness);
+
+ // from CcnxApp
+ virtual void
+ OnInterest (const ns3::Ptr<const ns3::CcnxInterestHeader> &interest, ns3::Ptr<ns3::Packet> packet);
+
+ virtual void
+ OnContentObject (const ns3::Ptr<const ns3::CcnxContentObjectHeader> &contentObject,
+ ns3::Ptr<ns3::Packet> payload);
+
+private:
+ CcnxFilterEntryContainer<InterestCallback>::type::iterator
+ InterestCallbackLookup (const ns3::CcnxNameComponents &name);
+
+ CcnxFilterEntryContainer<DataCallback>::type::iterator
+ DataCallbackLookup (const ns3::CcnxNameComponents &name);
+
+private:
+ ns3::UniformVariable m_rand; // nonce generator
+
+ CcnxFilterEntryContainer<DataCallback>::type m_dataCallbacks;
+ CcnxFilterEntryContainer<InterestCallback>::type m_interestCallbacks;
+};
+
+typedef boost::shared_ptr<CcnxWrapper> CcnxWrapperPtr;
+
+} // Sync
+
+#endif // SYNC_CCNX_WRAPPER_H
diff --git a/ns3/sync-log.h b/ns3/sync-log.h
index 9ab4843..6dbc930 100644
--- a/ns3/sync-log.h
+++ b/ns3/sync-log.h
@@ -23,6 +23,24 @@
#ifndef SYNC_LOG_H
#define SYNC_LOG_H
+#ifdef NS3_MODULE
+
+#include <ns3/log.h>
+
+#define INIT_LOGGER(name) NS_LOG_COMPONENT_DEFINE(name);
+
+#define _LOG_INFO(x) NS_LOG_INFO(x)
+
+#define _LOG_DEBUG(x) NS_LOG_DEBUG(x)
+
+#define _LOG_TRACE(x) NS_LOG_LOGIC(x)
+
+#define _LOG_FUNCTION(x) NS_LOG_FUNCTION(x)
+
+#define _LOG_FUNCTION_NOARGS NS_LOG_FUNCTION_NOARGS
+
+#else
+
#ifdef HAVE_LOG4CXX
#include <log4cxx/logger.h>
@@ -30,7 +48,10 @@
#define INIT_LOGGER(name) \
static log4cxx::LoggerPtr staticModuleLogger = log4cxx::Logger::getLogger (name);
-#define _LOG_DEBUG(x) \
+#define _LOG_INFO(x) \
+ LOG4CXX_INFO(staticModuleLogger, x);
+
+#define _LOG_DEBUG(x) \
LOG4CXX_DEBUG(staticModuleLogger, x);
#define _LOG_TRACE(x) \
@@ -51,6 +72,7 @@
#define _LOG_FUNCTION(x)
#define _LOG_FUNCTION_NOARGS
#define _LOG_TRACE(x)
+#define _LOG_INFO(x)
#define INIT_LOGGERS(x)
#ifdef _DEBUG
@@ -68,4 +90,6 @@
#endif // HAVE_LOG4CXX
+#endif // NS3_MODULE
+
#endif // SYNC_LOG_H
diff --git a/ns3/sync-scheduler.cc b/ns3/sync-scheduler.cc
index b236c02..7f39f38 100644
--- a/ns3/sync-scheduler.cc
+++ b/ns3/sync-scheduler.cc
@@ -27,6 +27,7 @@
using namespace boost;
using namespace std;
+using namespace ns3;
INIT_LOGGER ("Scheduler");
@@ -41,22 +42,46 @@
}
void
-Scheduler::schedule (const boost::posix_time::time_duration &reltime, Event event, uint32_t label)
+Scheduler::eventWrapper (Event event)
{
- ns3::Seconds (reltime.total_seconds()) + ns3::MilliSeconds (reltime.milliseconds ()) + ns3::MicroSeconds (reltime.microseconds ());
+ event ();
+}
+
+void
+Scheduler::schedule (const TimeDuration &reltime, Event event, uint32_t label)
+{
+ list< EventId > &eventsForLabel = m_labeledEvents [label];
+ list< EventId >::iterator i = eventsForLabel.begin ();
+ while (i != eventsForLabel.end ())
+ {
+ if (i->IsExpired ())
+ {
+ list< EventId >::iterator next = i;
+ next ++;
+ eventsForLabel.erase (i);
+ i = next;
+ }
+ else
+ i ++;
+ }
+
+ ns3::EventId eventId = ns3::Simulator::Schedule (reltime, Scheduler::eventWrapper, event);
+ eventsForLabel.push_back (eventId);
}
void
Scheduler::cancel (uint32_t label)
{
- // {
- // // cout << "Canceling label " << label << " size: " << m_events.size () << endl;
- // lock_guard<mutex> lock (m_eventsMutex);
- // m_events.get<byLabel> ().erase (label);
- // // cout << "Canceled label " << label << " size: " << m_events.size () << endl;
- // }
- // m_eventsCondition.notify_one ();
- // m_thread.interrupt (); // interrupt sleep, if currently sleeping
+ list< EventId > &eventsForLabel = m_labeledEvents [label];
+
+ for (list< EventId >::iterator i = eventsForLabel.begin ();
+ i != eventsForLabel.end ();
+ i++)
+ {
+ i->Cancel ();
+ }
+
+ eventsForLabel.clear ();
}
diff --git a/ns3/sync-scheduler.h b/ns3/sync-scheduler.h
index d3b536a..f10dc70 100644
--- a/ns3/sync-scheduler.h
+++ b/ns3/sync-scheduler.h
@@ -23,9 +23,17 @@
#ifndef SYNC_SCHEDULER_H
#define SYNC_SCHEDULER_H
-#include <boost/date_time/posix_time/posix_time.hpp>
+#include <ns3/nstime.h>
+#include <ns3/event-id.h>
+#include <list>
+#include <map>
+
#include "sync-event.h"
+#define TIME_SECONDS(number) ns3::Seconds(number)
+#define TIME_MILLISECONDS(number) ns3::MilliSeconds(number)
+typedef ns3::Time TimeDuration;
+
namespace Sync {
/**
@@ -62,7 +70,7 @@
* @param label Label for the event
*/
void
- schedule (const boost::posix_time::time_duration &reltime, Event event, uint32_t label);
+ schedule (const TimeDuration &reltime, Event event, uint32_t label);
/**
* @brief Cancel all events for the label
@@ -70,6 +78,13 @@
*/
void
cancel (uint32_t label);
+
+private:
+ static void
+ eventWrapper (Event event);
+
+private:
+ std::map< uint32_t, std::list< ns3::EventId > > m_labeledEvents;
};
}
diff --git a/wscript b/wscript
index 3eab13e..21824d7 100644
--- a/wscript
+++ b/wscript
@@ -65,7 +65,7 @@
target = "sync-ns3",
features=['cxx', 'cxxshlib'],
source = [
- # 'ns3/sync-ccnx-wrapper.cc',
+ 'ns3/sync-ccnx-wrapper.cc',
'ns3/sync-ns3-name-info.cc',
'ns3/sync-scheduler.cc',
@@ -105,7 +105,7 @@
'ccnx/sync-app-data-publish.cc',
'ccnx/sync-app-socket-c.cc',
'ccnx/sync-app-socket.cc',
-
+
'model/sync-diff-leaf.cc',
'model/sync-diff-state.cc',
'model/sync-digest.cc',