docs: Adding forwarding strategy example
diff --git a/docs/source/_static/code-samples/custom-strategy.cc b/docs/source/_static/code-samples/custom-strategy.cc
new file mode 100644
index 0000000..3b1cea1
--- /dev/null
+++ b/docs/source/_static/code-samples/custom-strategy.cc
@@ -0,0 +1,117 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+// custom-strategy.cc
+
+#include "custom-strategy.h"
+#include "ns3/ndn-fib.h"
+#include "ns3/ndn-fib-entry.h"
+#include "ns3/ndn-pit-entry.h"
+#include "ns3/ndn-interest.h"
+
+namespace ns3 {
+namespace ndn {
+namespace fw {
+
+NS_OBJECT_ENSURE_REGISTERED(CustomStrategy);
+
+LogComponent CustomStrategy::g_log = LogComponent (CustomStrategy::GetLogName ().c_str ());
+
+std::string
+CustomStrategy::GetLogName ()
+{
+ return "ndn.fw.CustomStrategy";
+}
+
+TypeId
+CustomStrategy::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::ndn::fw::CustomStrategy")
+ .SetGroupName ("Ndn")
+ .SetParent <BaseStrategy> ()
+ .AddConstructor <CustomStrategy> ()
+
+ // .AddAttribute ("Attribute", "Attribute spec",
+ // StringValue ("DefaultValue"),
+ // MakeStringAccessor (&BaseStrategy::m_variable),
+ // MakeStringChecker ())
+ ;
+ return tid;
+}
+
+CustomStrategy::CustomStrategy ()
+ : m_counter (0)
+{
+}
+
+bool
+CustomStrategy::DoPropagateInterest (Ptr<Face> inFace,
+ Ptr<const InterestHeader> header,
+ Ptr<const Packet> origPacket,
+ Ptr<pit::Entry> pitEntry)
+{
+ typedef fib::FaceMetricContainer::type::index<fib::i_metric>::type FacesByMetric;
+ FacesByMetric &faces = pitEntry->GetFibEntry ()->m_faces.get<fib::i_metric> ();
+ FacesByMetric::iterator faceIterator = faces.begin ();
+
+ int propagatedCount = 0;
+
+ // forward to best-metric face
+ if (faceIterator != faces.end ())
+ {
+ if (TrySendOutInterest (inFace, faceIterator->m_face, header, origPacket, pitEntry))
+ propagatedCount ++;
+
+ faceIterator ++;
+ }
+
+ // forward to second-best-metric face
+ if (faceIterator != faces.end ())
+ {
+ if (TrySendOutInterest (inFace, faceIterator->m_face, header, origPacket, pitEntry))
+ propagatedCount ++;
+
+ faceIterator ++;
+ }
+ return propagatedCount > 0;
+}
+
+void
+CustomStrategy::DidSendOutInterest (Ptr<Face> outFace,
+ Ptr<const InterestHeader> header,
+ Ptr<const Packet> origPacket,
+ Ptr<pit::Entry> pitEntry)
+{
+ m_counter ++;
+}
+
+void
+CustomStrategy::WillEraseTimedOutPendingInterest (Ptr<pit::Entry> pitEntry)
+{
+ for (pit::Entry::out_container::iterator face = pitEntry->GetOutgoing ().begin ();
+ face != pitEntry->GetOutgoing ().end ();
+ face ++)
+ {
+ m_counter --;
+ }
+
+ BaseStrategy::WillEraseTimedOutPendingInterest (pitEntry);
+}
+
+
+void
+CustomStrategy::WillSatisfyPendingInterest (Ptr<Face> inFace,
+ Ptr<pit::Entry> pitEntry)
+{
+ for (pit::Entry::out_container::iterator face = pitEntry->GetOutgoing ().begin ();
+ face != pitEntry->GetOutgoing ().end ();
+ face ++)
+ {
+ m_counter --;
+ }
+
+ BaseStrategy::WillSatisfyPendingInterest (inFace, pitEntry);
+}
+
+
+} // namespace fw
+} // namespace ndn
+} // namespace ns3
diff --git a/docs/source/_static/code-samples/custom-strategy.h b/docs/source/_static/code-samples/custom-strategy.h
new file mode 100644
index 0000000..4a4476d
--- /dev/null
+++ b/docs/source/_static/code-samples/custom-strategy.h
@@ -0,0 +1,67 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+
+// custom-strategy.h
+
+#ifndef CUSTOM_STRATEGY_H
+#define CUSTOM_STRATEGY_H
+
+#include "ns3/log.h"
+#include "ns3/ndn-forwarding-strategy.h"
+#include "ns3/ndn-l3-protocol.h"
+
+namespace ns3 {
+namespace ndn {
+namespace fw {
+
+typedef ForwardingStrategy BaseStrategy;
+
+class CustomStrategy:
+ public BaseStrategy
+{
+public:
+ static TypeId
+ GetTypeId ();
+
+ static std::string
+ GetLogName ();
+
+ CustomStrategy ();
+
+protected:
+ virtual bool
+ DoPropagateInterest (Ptr<Face> incomingFace,
+ Ptr<const InterestHeader> header,
+ Ptr<const Packet> origPacket,
+ Ptr<pit::Entry> pitEntry);
+
+public:
+ virtual void
+ DidSendOutInterest (Ptr<Face> outFace,
+ Ptr<const InterestHeader> header,
+ Ptr<const Packet> origPacket,
+ Ptr<pit::Entry> pitEntry);
+
+ virtual void
+ WillEraseTimedOutPendingInterest (Ptr<pit::Entry> pitEntry);
+
+ virtual void
+ WillSatisfyPendingInterest (Ptr<Face> inFace,
+ Ptr<pit::Entry> pitEntry);
+
+protected:
+ static LogComponent g_log;
+
+// private:
+// std::string m_variable;
+
+private:
+ uint32_t m_counter;
+};
+
+
+
+} // namespace fw
+} // namespace ndn
+} // namespace ns3
+
+#endif // CUSTOM_STRATEGY_H
diff --git a/docs/source/fw.rst b/docs/source/fw.rst
new file mode 100644
index 0000000..21e3531
--- /dev/null
+++ b/docs/source/fw.rst
@@ -0,0 +1,65 @@
+
+Forwarding Strategies
+=====================
+
+ndnSIM provides simple ways to experiment with custom Interest/Data forwarding strategies.
+A new forwarding strategy can be implement completely different processing or override just specific actions/events of the :ndnsim:`forwarding strategy interface <ndn::ForwardingStrategy>`.
+Please refer to :ndnsim:`API documentation <ndn::ForwardingStrategy>` of the forwarding strategy interface, which lists all default actions/events.
+
+Writing your own custom strategy
+++++++++++++++++++++++++++++++++
+
+First step in creating your own strategy is to decide which existing strategy you want to extend. You can either use realize :ndnsim:`forwarding strategy interface <ndn::ForwardingStrategy>` (:ndnsim:`ndn::ForwardingStrategy::DoPropagateInterest` call must be implemented) or extended one of the available forwarding strategies (:ndnsim:`fw::BestRoute` or :ndnsim:`fw::Flooding`).
+The following example assumes that we are realizing :ndnsim:`forwarding strategy interface <ndn::ForwardingStrategy>`.
+
+The follwoing are template strategy h/cc files:
+
+.. literalinclude:: _static/code-samples/custom-strategy.h
+ :language: c++
+ :linenos:
+ :lines: 1-36,51-55,59-
+
+.. literalinclude:: _static/code-samples/custom-strategy.cc
+ :language: c++
+ :linenos:
+ :lines: 1-40,42-50,75-76,115-
+
+After having the template, we can fill the necesasry functionality.
+
+Let us say, that we want Interest be forwarded to first two best-metric faces specified by FIB.
+That is, if node has two or more alternative paths to forward the Interests, this Interest will be forwarded to the best two neighbors.
+The following implementation of CustomStrategy::DoPropagateInterest accomplishes the task:
+
+.. literalinclude:: _static/code-samples/custom-strategy.cc
+ :language: c++
+ :linenos:
+ :lines: 45-75
+ :emphasize-lines: 7-30
+
+After the compilation, you can use ``"ns3::ndn::fw::CustomStrategy"`` as a parameter to :ndnsim:`ndn::StackHelper::SetForwardingStrategy` helper method.
+
+ .. as well as NS_LOG=ndn.fw.CustomStrategy when running in a debug mode
+
+Extending strategy
+++++++++++++++++++
+
+If you need more customization for the forwarding strategy, there are many forwarding strategy events that can be overriden.
+For example, if we want to perform special logging of all forwarded, timed out, and satisfied Intersts, we can override the following events (for more events, refer to :ndnsim:`ForwardingStrategy API documentation <ForwardingStrategy>`):
+
+- :ndnsim:`DidSendOutInterest <ForwardingStrategy::DidSendOutInterest>`, which fired just after forwarding the Interest
+
+- :ndnsim:`WillEraseTimedOutPendingInterest <ForwardingStrategy::WillEraseTimedOutPendingInterest>`, which fired just before PIT entry is removed by timeout
+
+- :ndnsim:`WillSatisfyPendingInterest <ForwardingStrategy::WillSatisfyPendingInterest>`, which fired just before Interest will be satisfied.
+
+The highlighted ares of the following code demonstrates how it can be impelmented:
+
+.. literalinclude:: _static/code-samples/custom-strategy.h
+ :language: c++
+ :linenos:
+ :emphasize-lines: 37-50,56-58
+
+.. literalinclude:: _static/code-samples/custom-strategy.cc
+ :language: c++
+ :linenos:
+ :emphasize-lines: 41,51-74,77-114
diff --git a/docs/source/index.rst b/docs/source/index.rst
index 510cf3a..4391e2f 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -10,6 +10,7 @@
intro
helpers
+ fw
applications
examples
faq