GetPrefix was added to Producer app
diff --git a/apps/ccnx-producer.cc b/apps/ccnx-producer.cc
index 7e0757a..d320a2d 100644
--- a/apps/ccnx-producer.cc
+++ b/apps/ccnx-producer.cc
@@ -34,44 +34,18 @@
static TypeId tid = TypeId ("ns3::CcnxProducer")
.SetParent<Application> ()
.AddConstructor<CcnxProducer> ()
- // Alex: this is incorrect. SetNode call is not called if face is created using this accessor
- // .AddAttribute ("Face","Local face to be used",
- // PointerValue (CreateObject<CcnxLocalFace> ()),
- // MakePointerAccessor (&CcnxProducer::m_face),
- // MakePointerChecker<CcnxLocalFace> ())
- .AddAttribute ("Ccnx","Ccnx is needed to access ContentStore",
- PointerValue (NULL),
- MakePointerAccessor (&CcnxProducer::m_ccnx),
- MakePointerChecker<Ccnx> ())
-
- /*.AddAttribute ("InterestName","CcnxName of the Interest (use CcnxNameComponents)",
- PointerValue (CreateObject<CcnxNameComponents> ()),
- MakePointerAccessor (&CcnxConsumer::m_interestName),
- MakePointerChecker<CcnxNameComponents> ())
- .AddAttribute ("LifeTime", "LifeTime fo interest packet",
- TimeValue (Seconds (4.0)),
- MakeTimeAccessor (&CcnxConsumer::m_interestLifeTime),
- MakeTimeChecker ())
- .AddAttribute ("MinSuffixComponents", "MinSuffixComponents",
- IntegerValue(-1),
- MakeIntegerAccessor(&CcnxConsumer::m_minSuffixComponents),
- MakeIntegerChecker<int32_t>())
- .AddAttribute ("MaxSuffixComponents", "MaxSuffixComponents",
- IntegerValue(-1),
- MakeIntegerAccessor(&CcnxConsumer::m_maxSuffixComponents),
- MakeIntegerChecker<int32_t>())
- .AddAttribute ("ChildSelector", "ChildSelector",
- BooleanValue(false),
- MakeBooleanAccessor(&CcnxConsumer::m_childSelector),
- MakeBooleanChecker())
- .AddAttribute ("Exclude", "only simple name matching is supported (use CcnxNameComponents)",
- PointerValue (CreateObject<CcnxNameComponents> ()),
- MakePointerAccessor (&CcnxConsumer::m_exclude),
- MakePointerChecker<CcnxNameComponents> ())*/
- .AddAttribute ("Capacity", "Capacity of the ContentStore",
+ /*.AddAttribute ("Capacity", "Capacity of the ContentStore",
UintegerValue(100),
MakeUintegerAccessor(&CcnxProducer::m_storeCapacity),
- MakeUintegerChecker<uint32_t>())
+ MakeUintegerChecker<uint32_t>())*/
+ .AddAttribute ("Prefix","Prefix, for which producer has the data",
+ CcnxNameComponentsValue (),
+ MakeCcnxNameComponentsAccessor (&CcnxProducer::m_prefix),
+ MakeCcnxNameComponentsChecker ())
+ .AddAttribute ("PayloadSize", "Virtual payload size for Content packets",
+ UintegerValue(100),
+ MakeUintegerAccessor(&CcnxProducer::m_virtualPayloadSize),
+ MakeUintegerChecker<uint32_t>())
.AddTraceSource ("InterestTrace", "Interests that were received",
MakeTraceSourceAccessor (&CcnxProducer::m_interestsTrace))
.AddTraceSource ("ContentObjectTrace", "ContentObjects that were sent",
@@ -104,15 +78,58 @@
CcnxProducer::StartApplication () // Called at time specified by Start
{
NS_LOG_FUNCTION_NOARGS ();
-// ScheduleNextTx();
+
+ NS_ASSERT_MSG (m_face == 0, "Face should not exist");
+ m_face = Create<CcnxLocalFace> ();
+
+ // step 1. Set up forwarding from face to application
+ m_face->SetNode (GetNode ());
+ m_face->SetInterestHandler (MakeCallback (&CcnxProducer::OnInterest, this));
+
+ // step 2. Set up forwarding to and from ccnx
+ NS_ASSERT_MSG (GetNode ()->GetObject<Ccnx> () !=0,
+ "Ccnx stack should be installed on the node " << GetNode ());
+ GetNode ()->GetObject<Ccnx> ()->AddFace (m_face);
+ //Add (const CcnxNameComponents &prefix, Ptr<CcnxFace> face, int32_t metric);
+ GetNode ()->GetObject<Ccnx> ()->GetObject<CcnxFib> ()->Add(m_prefix, m_face, 0);
+ // step 3. Enable face
+ m_face->SetUp ();
}
void
CcnxProducer::StopApplication () // Called at time specified by Stop
{
NS_LOG_FUNCTION_NOARGS ();
+}
+
+void
+CcnxProducer::OnInterest(const Ptr<const CcnxInterestHeader> &interest)
+{
+ NS_LOG_FUNCTION (this);
+
+
+
+ //Ptr<Packet> data = Lookup (interest);
+
+
+
+ Ptr<Packet> incomingPacket = Create<Packet>(m_virtualPayloadSize);
+ incomingPacket->AddHeader (*interest);
+ m_interestsTrace(m_face,incomingPacket);
+
+
+
+ static CcnxContentObjectTail tail; ///< \internal for optimization purposes
+ Ptr<Packet> outgoingPacket = Create<Packet> (m_virtualPayloadSize);
+ Ptr<CcnxContentObjectHeader> header = Create<CcnxContentObjectHeader>();
+ header->SetName(Create<CcnxNameComponents>(interest->GetName()));
+ outgoingPacket->AddHeader(*header);
+ outgoingPacket->AddTrailer (tail);
+
+ m_contentObjectsTrace(m_face,outgoingPacket);
- CancelEvents ();
+ m_face->ReceiveFromApplication(outgoingPacket);
+
}
void
@@ -122,48 +139,26 @@
// Simulator::Cancel (m_sendEvent);
}
-
-/*void
-CcnxProducer::ScheduleNextTx ()
+
+CcnxNameComponents
+CcnxProducer::GetPrefix() const
{
- NS_LOG_FUNCTION_NOARGS ();
-
- Time nextTime = Seconds(m_offTime);
- m_sendEvent = Simulator::Schedule (nextTime, &CcnxConsumer::SendPacket, this);
- }
- */
+ return m_prefix;
+}
-/*void
-CcnxConsumer::SendPacket ()
- {
- NS_LOG_FUNCTION_NOARGS ();
- NS_LOG_INFO ("Sending Interest at " << Simulator::Now ());
-
- uint32_t randomNonce = UniformVariable().GetInteger(1, std::numeric_limits<uint32_t>::max ());
- CcnxInterestHeader interestHeader;
- interestHeader.SetNonce(randomNonce);
- interestHeader.SetName(m_interestName);
- interestHeader.SetInterestLifetime(m_interestLifeTime);
- interestHeader.SetChildSelector(m_childSelector);
- interestHeader.SetExclude(m_exclude);
- interestHeader.SetMaxSuffixComponents(m_maxSuffixComponents);
- interestHeader.SetMinSuffixComponents(m_minSuffixComponents);
-
- Ptr<Packet> packet = Create<Packet> ();
- packet->AddHeader (interestHeader);
-
- m_face->Receive(packet);
-
- ScheduleNextTx();
- }*/
-
-uint32_t
+/*uint32_t
CcnxProducer::GetStoreCapacity()
{
- return m_storeCapacity;
+ return m_storeCapacity;
}
void
+CcnxProducer::SetStoreCapacity(uint32_t capacity)
+{
+ m_storeCapacity = capacity;
+}
+ */
+/*void
CcnxProducer::HandlePacket(const Ptr<CcnxFace> &face, const Ptr<const Packet> &packet)
{
uint8_t type[2];
@@ -182,11 +177,41 @@
{
m_contentObjectsTrace(face,packet);
}
-}
+}*/
+
+/*Ptr<Packet>
+CcnxProducer::Lookup (Ptr<const CcnxInterestHeader> interest)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ DataStoreContainer::type::iterator it = m_availableData.get<i_prefix> ().find (interest->GetName ());
+
+ if (it != m_availableData.end ())
+ {
+ // return fully formed CCNx packet
+ return it->GetFullyFormedCcnxPacket ();
+ }
+
+ return 0;
+}
void
-CcnxProducer::AddContentStoreEntry (Ptr<CcnxContentObjectHeader> header, Ptr<const Packet> packet)
+CcnxProducer::Add (Ptr<CcnxContentObjectHeader> header, Ptr<const Packet> packet)
{
- // m_ccnx->m_contentStore->Add (header, packet);
-}
+ NS_LOG_FUNCTION_NOARGS ();
+ DataStoreContainer::type::iterator it = m_availableData.get<i_prefix> ().find (header->GetName ());
+
+ if (it == m_availableData.end ())
+ { // add entry to the top
+ m_availableData.get<i_mru> ().push_front (DataStoreEntry (header, packet));
+
+ if (m_availableData.size () > m_storeCapacity)
+ m_availableData.get<i_mru> ().pop_back ();
+ }
+ else
+ {
+ // promote entry to the top
+ //m_contentStore.get<i_mru> ().relocate (m_contentStore.get<i_mru> ().begin (),
+ // m_contentStore.project<i_mru> (it));
+ }
+}*/
}
diff --git a/apps/ccnx-producer.h b/apps/ccnx-producer.h
index 55049dd..840400b 100644
--- a/apps/ccnx-producer.h
+++ b/apps/ccnx-producer.h
@@ -45,10 +45,73 @@
#include "ns3/header.h"
#include "ns3/ccnx.h"
#include "ns3/ccnx-content-object-header.h"
+#include "ns3/ccnx-name-components.h"
+#include "ns3/ccnx-fib.h"
+
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/tag.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <boost/multi_index/sequenced_index.hpp>
+#include <boost/multi_index/hashed_index.hpp>
+#include <boost/multi_index/mem_fun.hpp>
namespace ns3
{
+ class DataStoreEntry
+ {
+ public:
+ /**
+ * \brief Construct data store entry
+ *
+ * \param header Parsed CcnxContentObject header
+ * \param packet Original CCNx packet
+ *
+ * The constructor will make a copy of the supplied packet and calls
+ * RemoveHeader and RemoveTail on the copy.
+ */
+ DataStoreEntry (Ptr<CcnxContentObjectHeader> header, Ptr<const Packet> packet);
+
+ /**
+ * \brief Get prefix of the stored entry
+ * \returns prefix of the stored entry
+ */
+ inline const CcnxNameComponents&
+ GetName () const;
+
+ /**
+ * \brief Get CcnxContentObjectHeader of the stored entry
+ * \returns CcnxContentObjectHeader of the stored entry
+ */
+ inline Ptr<const CcnxContentObjectHeader>
+ GetHeader () const;
+
+ /**
+ * \brief Get content of the stored entry
+ * \returns content of the stored entry
+ */
+ inline Ptr<const Packet>
+ GetPacket () const;
+
+ /**
+ * \brief Convenience method to create a fully formed CCNx packet from stored header and content
+ * \returns A read-write copy of the packet with CcnxContentObjectHeader and CcxnContentObjectTail
+ */
+ Ptr<Packet>
+ GetFullyFormedCcnxPacket () const;
+
+ // Copy constructor is required by the container. Though, we're
+ // storing only two pointers, so shouldn't be a problem
+ // private:
+ // CcnxContentStoreEntry (const CcnxContentStoreEntry &); ///< disabled copy constructor
+ // CcnxContentStoreEntry& operator= (const CcnxContentStoreEntry&); ///< disabled copy operator
+
+ private:
+ //Ptr<CcnxContentObjectHeader> m_header; ///< \brief non-modifiable CcnxContentObjectHeader
+ //Ptr<Packet> m_packet; ///< \brief non-modifiable content of the ContentObject packet
+ };
+
+
class CcnxProducer: public Application
{
public:
@@ -58,9 +121,26 @@
virtual ~CcnxProducer ();
- void HandlePacket (const Ptr<CcnxFace> &face, const Ptr<const Packet> &packet);
- uint32_t GetStoreCapacity();
- void AddContentStoreEntry (Ptr<CcnxContentObjectHeader> header, Ptr<const Packet> packet);
+ //void HandlePacket (const Ptr<CcnxFace> &face, const Ptr<const Packet> &packet);
+ //uint32_t GetStoreCapacity();
+ //void SetStoreCapacity(uint32_t capacity);
+ //void AddContentStoreEntry (Ptr<CcnxContentObjectHeader> header, Ptr<const Packet> packet);
+
+ void OnInterest(const Ptr<const CcnxInterestHeader> &interest);
+
+ CcnxNameComponents GetPrefix() const;
+ /**
+ * \brief Add a new content to the data store.
+ *
+ * \param header Fully parsed CcnxContentObjectHeader
+ * \param packet Fully formed CCNx packet to add to content store
+ * (will be copied and stripped down of headers)
+ *
+ * If entry with the same prefix exists, the old entry will be
+ * promoted to the top of the MRU hash
+ */
+ //void
+ //Add (Ptr<CcnxContentObjectHeader> header, Ptr<const Packet> packet);
protected:
virtual void DoDispose (void);
@@ -69,48 +149,59 @@
virtual void StartApplication (void); // Called at time specified by Start
virtual void StopApplication (void); // Called at time specified by Stop
+ /**
+ * \brief Find corresponding CS entry for the given interest
+ *
+ * \param interest Interest for which matching content store entry
+ * will be searched
+ *
+ * If an entry is found, it is promoted to the top of most recent
+ * used entries index, \see m_contentStore
+ */
+ //Ptr<Packet>
+ //Lookup (Ptr<const CcnxInterestHeader> interest);
+
+
Ptr<Ccnx> m_ccnx;
Time m_offTime;
- //Ptr<CcnxNameComponents> m_interestName;
- //Time m_interestLifeTime;
- //int32_t m_minSuffixComponents;
- //int32_t m_maxSuffixComponents;
- //bool m_childSelector;
- //Ptr<CcnxNameComponents> m_exclude;
- //uint32_t m_initialNonce;
-
+
//EventId m_sendEvent; // Eventid of pending "send packet" event
TypeId m_tid;
Ptr<CcnxLocalFace> m_face;
- uint32_t m_storeCapacity;
-
+ /*struct DataStoreContainer
+ {
+ typedef
+ boost::multi_index::multi_index_container<
+ DataStoreEntry,
+ boost::multi_index::indexed_by<
+ boost::multi_index::hashed_unique<
+ boost::multi_index::tag<__ccnx_private::i_prefix>,
+ boost::multi_index::const_mem_fun<DataStoreEntry,
+ const CcnxNameComponents&,
+ &DataStoreEntry::GetName>,
+ CcnxPrefixHash>,
+ boost::multi_index::sequenced<boost::multi_index::tag<__ccnx_private::i_mru> >
+#ifdef _DEBUG
+ ,
+ boost::multi_index::ordered_unique<
+ boost::multi_index::tag<__ccnx_private::i_ordered>,
+ boost::multi_index::const_mem_fun<DataStoreEntry,
+ const CcnxNameComponents&,
+ &CcnxContentStoreEntry::GetName>
+ >
+#endif
+ >
+ > type;
+ };*/
+
//helpers
void CancelEvents ();
-
- void Construct (Ptr<Node> n,
- std::string tid,
- const Time& offtime,
- Ptr<CcnxLocalFace> face,
- Ptr<CcnxNameComponents> nameComponents,
- const Time& lifetime,
- const int32_t& minSuffixComponents,
- const int32_t& maxSuffixComponents,
- const bool childSelector,
- Ptr<CcnxNameComponents> exclude,
- const uint32_t& initialNonce
- );
-
- // Event handlers
- void StartSending ();
- void StopSending ();
- void SendPacket ();
- //typedef Callback<void,const Ptr<CcnxFace>&,const Ptr<const Packet>& > ProtocolHandler;
-
-private:
- void ScheduleNextTx ();
- //typedef Callback<void,const Ptr<CcnxFace>&,const Ptr<const Packet>& > ProtocolHandler;
-
+
+ //DataStoreContainer::type m_availableData;
+ //uint32_t m_storeCapacity;
+ uint32_t m_virtualPayloadSize;
+ CcnxNameComponents m_prefix;
TracedCallback<const Ptr<CcnxFace>&,const Ptr<const Packet>& > m_interestsTrace;
TracedCallback<const Ptr<CcnxFace>&,const Ptr<const Packet>& > m_contentObjectsTrace;
};