docs: Add guide on how to simulate real apps in ndnSIM
Change-Id: I3694a8791b9540fc1b926a83ff55421b47e0f2a2
diff --git a/docs/source/guide-to-simulate-real-apps.rst b/docs/source/guide-to-simulate-real-apps.rst
index ab73f8d..5d7b8ac 100644
--- a/docs/source/guide-to-simulate-real-apps.rst
+++ b/docs/source/guide-to-simulate-real-apps.rst
@@ -1,4 +1,216 @@
-Simulating real applications
-============================
+Simulating real NDN applications
+================================
-TODO
+The version of `ndn-cxx library <http://named-data.net/doc/ndn-cxx/>`__ bundled with ndnSIM includes
+a modified version of :ndnsim:`ndn::Face` to directly send and receive Interest and Data packets to
+and from the simulated instances of NFD. With this modification, ndnSIM enables support to simulate
+real NDN applications written against the ndn-cxx, if they satisfy requirements listed in this guide
+or can be modified to satisfy these requirements.
+
+
+Requirements
+++++++++++++
+
+#. **Source code of the application must be available**
+
+ The application (parts of the application) needs to be compiled against the ndnSIM version of
+ ndn-cxx library.
+
+#. **Source code should separate** ``main`` **function from the functional components of the
+ application that will be simulated**
+
+ The entry point to the application (its functional component) will be NS-3 application class,
+ which should be able to create and destroy an instance of the simulated component when scheduled
+ by the scenario.
+
+#. **The application should not use global variables, if they define a state for the application
+ instance**
+
+ ndnSIM should be able to create multiple different instances of the application, e.g., for each
+ simulated node.
+
+ Exception to this requirement is :ndnsim:`ndn::Scheduler <ndn::util::scheduler::Scheduler>`: its
+ implementation has been rewired to use NS-3's scheduling routines.
+
+#. **The application MUST NOT contain any GUI or command-line terminal interactions**
+
+#. **The application SHOULD NOT use disk operations, unless application instances access unique
+ parts of the file system**
+
+ In the simulated environment, all application instances will be accessing the same local file
+ system, which can result in undefined behavior if not properly handled.
+
+#. **The application MUST use a subset of** :ndnsim:`ndn::Face` **API:**
+
+ - If the application create :ndnsim:`ndn::Face`, it MUST BE created either with a default
+ constructor or constructor that accepts a single ``boost::asio::io_service`` parameter.
+
+ .. code-block:: c++
+
+ // Supported
+ ndn::Face face1();
+ ndn::Face face2(ioService);
+
+ // Not supported in ndnSIM
+ ndn::Face face4(host_name, port_number)
+ ndn::Face face3(transport);
+ // and others
+
+ - :ndnsim:`ndn::Face::getIoService()` should be used only to obtain a reference to
+ ``boost::asio::io_service``. **Application MUST NOT use any methods of**
+ ``boost::asio::io_service``, **otherwise the simulation will crash.**
+
+ .. code-block:: c++
+
+ ndn::Face face;
+ ...
+ // Supported (the rewired Scheduler implementation does not access io_service methods)
+ Scheduler scheduler(face.getIoService());
+
+ // Not supported in ndnSIM and will result in crash
+ face.getIoService().stop();
+
+
+ - Application should avoid use of :ndnsim:`Face::processEvents` or use it with caution
+
+ In real applications, processEvents blocks until some data is received or the timeout callback
+ is called. In this case, any variables created before calling this method will still exist
+ after the method returns. However, in ndnSIM, such an assumption cannot be made, since the
+ scope of a variable is local.
+
+ .. code-block:: c++
+
+ void
+ foo
+ {
+ ndn::Face face;
+ face.expressInterest(...);
+ face.setInterestFilter(...);
+
+ // ndnSIM version of processEvents will not block!
+ face.processEvents();
+ }
+ // after existing foo scope, face variable is deallocated and all scheduled operations
+ // will be canceled
+
+#. **Application (simulated component) MUST NOT create instances of** ``boost::asio::io_service``
+ **and use their methods**
+
+ ``boost::asio::io_service`` is inherently incompatible with NS-3, as both are providing mechanisms
+ for asynchronous event processing.
+
+#. We also recommend that functional part of the application accepts reference to the
+ :ndnsim:`KeyChain` instance, instead of creating instance itself.
+
+ When simulating non-security aspects of the application, in simulation scenario it will be
+ possible to use a dummy implementation of the :ndnsim:`KeyChain` that does not perform crypto
+ operations, but signs Data and Interests with fake signatures.
+
+ For example, this can be achieved by enabling the constructor of the real application to accept a reference
+ to the :ndnsim:`KeyChain`:
+
+ .. code-block:: c++
+
+ // Real applications should accept a reference to the KeyChain instance
+ RealApp::RealApp(KeyChain& keyChain)
+ : m_keyChain(keyChain)
+ {
+ }
+
+
+How to simulate real applications using ndnSIM
+++++++++++++++++++++++++++++++++++++++++++++++
+
+To simulate a real application, the simulation scenario should contain a class derived from
+``ns3::Application``. This class needs to create an instance of the :ndnsim:`ndn::Face` and/or real
+application in the overloaded ``StartApplication`` method. This class also need to ensure that the
+created instance is not deallocated until ``StopApplication`` method is called.
+
+For example, if the functional class of the real application looks like:
+
+.. literalinclude:: ../../examples/ndn-cxx-simple/real-app.hpp
+ :language: c++
+ :linenos:
+ :lines: 23-75
+
+
+The corresponding NS-3 "entry point" application class can be like this:
+
+.. literalinclude:: ../../examples/ndn-cxx-simple/real-app-starter.hpp
+ :language: c++
+ :linenos:
+ :lines: 25-65
+
+.. note::
+ There is a requirement that :ndnsim:`ndn::Face` MUST BE created within the context of a specific
+ ``ns3::Node``. In simple words this means that :ndnsim:`ndn::Face` constructor must be called
+ somewhere within the overloaded ``StartApplication`` method.
+
+ Attempt to create a :ndnsim:`ndn::Face` outside ``ns3::Node`` (e.g., if the example included
+ member variable ``Face m_face`` in ``RealAppStarter`` class) will result in simulation crash.
+
+The final step is to actually write a simulation scenario that defines network topology, routing
+information between nodes, on which nodes the application should be installed and when it should be
+started and stopped.
+
+For the trivial example, let us assume that we have only one simulation node and we want to start
+the application at time moment 6.5 seconds. This scenario can look like:
+
+.. literalinclude:: ../../examples/ndn-cxx-simple.cpp
+ :language: c++
+ :linenos:
+ :lines: 20-
+
+
+Example of a real application simulation
+++++++++++++++++++++++++++++++++++++++++
+
+To demonstrate functionality of ndnSIM in a more complex and realistic case, we will use the NDN
+ping application included as part of `NDN Essential Tools`_.
+
+For this example, we used a `scenario template repository`_ as a base to write simulation-specific
+extensions and define scenarios, and the `final version of the scenario is available in GitHub
+<https://github.com/named-data-ndnSIM/scenario-ndn-ping>`__.
+
+The following lists steps we did to simulate `ndnping` and `ndnpingserver` apps on a simple
+three-node topology:
+
+- forked `scenario template repository`_
+
+- imported the latest version of `NDN Essential Tools`_ source code as a git submodule
+
+- updated the build script (``wscript``) to compile the source code of ``ndnping`` and
+ ``ndnpingserver`` (with the exception of compilation units that contain ``main`` function) against
+ ndnSIM
+
+ `View changes <https://github.com/named-data-ndnSIM/scenario-ndn-ping/commit/74269dc4de6afe2b6e13a0bcc8c0faac350d8fa3>`__
+
+- defined ``PingClient`` and ``PingServer`` classes to hold state of application instances
+
+ `View changes <https://github.com/named-data-ndnSIM/scenario-ndn-ping/commit/4f087a16e3171af38c05b53c6cfd9e752e7cda72>`__
+
+- defined ``PingClientApp`` and ``PingServerApp`` NS-3 applications, that create and destroy
+ instances of ``PingClient`` and ``PingServer`` per NS-3 logic.
+
+ `View changes <https://github.com/named-data-ndnSIM/scenario-ndn-ping/commit/2b317860f55b71b34ffdccac31444246d9b804fe>`__
+
+- defined a simple scenario that creates a three node topology, installs NDN stacks, and installs
+ ``PingClientApp`` and ``PingServerApp`` applications on different simulation nodes.
+
+ `View changes <https://github.com/named-data-ndnSIM/scenario-ndn-ping/commit/2b317860f55b71b34ffdccac31444246d9b804fe>`__
+
+After all these steps, the repository is ready to run the simulation (see `README.md
+<https://github.com/named-data-ndnSIM/scenario-ndn-ping/blob/master/README.md>`__ for more details).
+
+
+.. note::
+ The listed steps did not include any modification of `NDN Essential Tools`_ source code.
+ However, this was not the case when we initially attempted to run the simulation, as the source
+ code was violating a few requirements of this guide. `The changes that we made
+ <https://github.com/named-data/ndn-tools/commit/1e7a7b20c93014e86639e3d07f357c95b48b34ac>`__ are
+ an example of how to adapt the source code to be compatible with ndnSIM simulations.
+
+
+.. _NDN Essential Tools: http://github.com/named-data/ndn-tools
+
+.. _scenario template repository: https://github.com/named-data-ndnSIM/scenario-template