model+ndn.cxx+apps: New application template (CallbackBasedApp) that can be used to prototype NS-3 applications in python

The current code allows simulating in python using ApiFace (passed basic tests)

Refs #1005 (http://redmine.named-data.net/)
diff --git a/apps/callback-based-app.cc b/apps/callback-based-app.cc
new file mode 100644
index 0000000..34c3de6
--- /dev/null
+++ b/apps/callback-based-app.cc
@@ -0,0 +1,79 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *                     Alexander Afanasyev
+ *                     Zhenkai Zhu
+ *
+ * GNU v3.0 license, See the LICENSE file for more information
+ *
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#include "callback-based-app.h"
+
+#include <ns3/log.h>
+
+NS_LOG_COMPONENT_DEFINE ("CallbackBasedApp");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (CallbackBasedApp);
+    
+TypeId
+CallbackBasedApp::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::CallbackBasedApp")
+    .SetGroupName ("Ndn")
+    .SetParent<Application> ()
+    .AddConstructor<CallbackBasedApp> ()
+
+    .AddAttribute ("OnStart", "OnStart callback",
+                   CallbackValue (),
+                   MakeCallbackAccessor (&CallbackBasedApp::m_onStart),
+                   MakeCallbackChecker ())
+
+    .AddAttribute ("OnStop", "OnStop callback",
+                   CallbackValue (),
+                   MakeCallbackAccessor (&CallbackBasedApp::m_onStop),
+                   MakeCallbackChecker ())
+    ;
+  return tid;
+}
+
+CallbackBasedApp::CallbackBasedApp ()
+{
+}
+
+CallbackBasedApp::~CallbackBasedApp ()
+{
+}
+
+void
+CallbackBasedApp::SetOnStartCallback (Callback< void, Ptr<Application> > onStart)
+{
+  m_onStart = onStart;
+}
+
+void
+CallbackBasedApp::SetOnStopCallback (Callback< void, Ptr<Application> > onStop)
+{
+  m_onStop = onStop;
+}
+
+void
+CallbackBasedApp::StartApplication ()
+{
+  NS_LOG_FUNCTION (this);
+  if (!m_onStart.IsNull ())
+    m_onStart (this);
+}
+
+void
+CallbackBasedApp::StopApplication ()
+{
+  NS_LOG_FUNCTION (this);
+  if (!m_onStop.IsNull ())
+    m_onStop (this);
+}
+
+}
diff --git a/apps/callback-based-app.h b/apps/callback-based-app.h
new file mode 100644
index 0000000..8cec638
--- /dev/null
+++ b/apps/callback-based-app.h
@@ -0,0 +1,68 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *                     Alexander Afanasyev
+ *                     Zhenkai Zhu
+ *
+ * GNU v3.0 license, See the LICENSE file for more information
+ *
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#ifndef NDN_CALLBACK_BASED_APP_H
+#define NDN_CALLBACK_BASED_APP_H
+
+#include "ns3/application.h"
+#include "ns3/ptr.h"
+#include "ns3/callback.h"
+
+namespace ns3 {
+
+/**
+ * @ingroup ndn
+ * @brief A meta application that can be used to create custom apps within Python bindings 
+ */
+class CallbackBasedApp: public Application
+{
+public:
+  static TypeId GetTypeId ();
+
+  /**
+   * @brief Default constructor
+   */
+  CallbackBasedApp ();
+
+  /**
+   * @brief Virtual destructor
+   */
+  virtual
+  ~CallbackBasedApp ();
+
+  /**
+   * @brief Define callback that will be fired when application need to start its work
+   */
+  void
+  SetOnStartCallback (Callback< void, Ptr<Application> > onStart);
+
+  /**
+   * @brief Define callback that will be fired when application need to stop its work
+   */
+  void
+  SetOnStopCallback (Callback< void, Ptr<Application> > onStart);
+
+protected:
+  // inherited from Application base class. Originally they were private
+  virtual void
+  StartApplication ();    ///< @brief Called at time specified by Start
+
+  virtual void
+  StopApplication ();     ///< @brief Called at time specified by Stop
+
+private:
+  Callback< void, Ptr<Application> > m_onStart;
+  Callback< void, Ptr<Application> > m_onStop;
+};
+
+} // ns3
+
+#endif // NDN_CALLBACK_BASED_APP_H
diff --git a/bindings/callbacks_list.py b/bindings/callbacks_list.py
index f4f57ce..1da8339 100644
--- a/bindings/callbacks_list.py
+++ b/bindings/callbacks_list.py
@@ -1,6 +1,10 @@
 callback_classes = [
+    ['void', 'ns3::Ptr<ns3::ndn::Interest const>', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
+    ['void', 'ns3::Ptr<ns3::ndn::Interest const>', 'ns3::Ptr<ns3::ndn::ContentObject const>', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
+    ['void', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
+    ['void', 'ns3::Ptr<ns3::ndn::Name const>', 'ns3::Ptr<ns3::ndn::Interest const>', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
     ['void', 'ns3::Ptr<ns3::ndn::Face>', 'ns3::Ptr<ns3::ndn::ContentObject>', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
     ['void', 'ns3::Ptr<ns3::ndn::Face>', 'ns3::Ptr<ns3::ndn::Interest>', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
-    ['void', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
+    ['void', 'ns3::Ptr<ns3::Application>', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
     ['void', 'ns3::Ptr<ns3::NetDevice>', 'ns3::Ptr<ns3::Packet const>', 'unsigned short', 'ns3::Address const&', 'ns3::Address const&', 'ns3::NetDevice::PacketType', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
 ]
diff --git a/bindings/modulegen__gcc_ILP32.py b/bindings/modulegen__gcc_ILP32.py
index 4255339..76287f8 100644
--- a/bindings/modulegen__gcc_ILP32.py
+++ b/bindings/modulegen__gcc_ILP32.py
@@ -210,6 +210,8 @@
     module.add_class('BooleanChecker', import_from_module='ns.core', parent=root_module['ns3::AttributeChecker'])
     ## boolean.h (module 'core'): ns3::BooleanValue [class]
     module.add_class('BooleanValue', import_from_module='ns.core', parent=root_module['ns3::AttributeValue'])
+    ## callback-based-app.h (module 'ndnSIM'): ns3::CallbackBasedApp [class]
+    module.add_class('CallbackBasedApp', parent=root_module['ns3::Application'])
     ## callback.h (module 'core'): ns3::CallbackChecker [class]
     module.add_class('CallbackChecker', import_from_module='ns.core', parent=root_module['ns3::AttributeChecker'])
     ## callback.h (module 'core'): ns3::CallbackImplBase [class]
@@ -381,8 +383,8 @@
     ## ndn-app-face.h (module 'ndnSIM'): ns3::ndn::AppFace [class]
     module.add_class('AppFace', parent=root_module['ns3::ndn::Face'])
     module.add_container('std::vector< ns3::Ptr< ns3::ndn::Face > >', 'ns3::Ptr< ns3::ndn::Face >', container_type='vector')
-    module.add_container('std::list< boost::reference_wrapper< std::string const > >', 'boost::reference_wrapper< std::basic_string< char, std::char_traits< char >, std::allocator< char > > const >', container_type='list')
     module.add_container('std::list< std::string >', 'std::string', container_type='list')
+    module.add_container('std::list< boost::reference_wrapper< std::string const > >', 'boost::reference_wrapper< std::basic_string< char, std::char_traits< char >, std::allocator< char > > const >', container_type='list')
     typehandlers.add_type_alias('ns3::ndn::ContentObject', 'ns3::ndn::ContentObjectHeader')
     typehandlers.add_type_alias('ns3::ndn::ContentObject*', 'ns3::ndn::ContentObjectHeader*')
     typehandlers.add_type_alias('ns3::ndn::ContentObject&', 'ns3::ndn::ContentObjectHeader&')
@@ -563,6 +565,7 @@
     register_Ns3AttributeValue_methods(root_module, root_module['ns3::AttributeValue'])
     register_Ns3BooleanChecker_methods(root_module, root_module['ns3::BooleanChecker'])
     register_Ns3BooleanValue_methods(root_module, root_module['ns3::BooleanValue'])
+    register_Ns3CallbackBasedApp_methods(root_module, root_module['ns3::CallbackBasedApp'])
     register_Ns3CallbackChecker_methods(root_module, root_module['ns3::CallbackChecker'])
     register_Ns3CallbackImplBase_methods(root_module, root_module['ns3::CallbackImplBase'])
     register_Ns3CallbackValue_methods(root_module, root_module['ns3::CallbackValue'])
@@ -3634,6 +3637,36 @@
                    [param('bool', 'value')])
     return
 
+def register_Ns3CallbackBasedApp_methods(root_module, cls):
+    ## callback-based-app.h (module 'ndnSIM'): ns3::CallbackBasedApp::CallbackBasedApp(ns3::CallbackBasedApp const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::CallbackBasedApp const &', 'arg0')])
+    ## callback-based-app.h (module 'ndnSIM'): ns3::CallbackBasedApp::CallbackBasedApp() [constructor]
+    cls.add_constructor([])
+    ## callback-based-app.h (module 'ndnSIM'): static ns3::TypeId ns3::CallbackBasedApp::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## callback-based-app.h (module 'ndnSIM'): void ns3::CallbackBasedApp::SetOnStartCallback(ns3::Callback<void, ns3::Ptr<ns3::Application>, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> onStart) [member function]
+    cls.add_method('SetOnStartCallback', 
+                   'void', 
+                   [param('ns3::Callback< void, ns3::Ptr< ns3::Application >, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'onStart')])
+    ## callback-based-app.h (module 'ndnSIM'): void ns3::CallbackBasedApp::SetOnStopCallback(ns3::Callback<void, ns3::Ptr<ns3::Application>, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> onStart) [member function]
+    cls.add_method('SetOnStopCallback', 
+                   'void', 
+                   [param('ns3::Callback< void, ns3::Ptr< ns3::Application >, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'onStart')])
+    ## callback-based-app.h (module 'ndnSIM'): void ns3::CallbackBasedApp::StartApplication() [member function]
+    cls.add_method('StartApplication', 
+                   'void', 
+                   [], 
+                   visibility='protected', is_virtual=True)
+    ## callback-based-app.h (module 'ndnSIM'): void ns3::CallbackBasedApp::StopApplication() [member function]
+    cls.add_method('StopApplication', 
+                   'void', 
+                   [], 
+                   visibility='protected', is_virtual=True)
+    return
+
 def register_Ns3CallbackChecker_methods(root_module, cls):
     ## callback.h (module 'core'): ns3::CallbackChecker::CallbackChecker() [constructor]
     cls.add_constructor([])
@@ -5629,8 +5662,6 @@
     cls.add_constructor([param('ns3::ndn::Name const &', 'arg0')])
     ## ndn-name.h (module 'ndnSIM'): ns3::ndn::Name::Name() [constructor]
     cls.add_constructor([])
-    ## ndn-name.h (module 'ndnSIM'): ns3::ndn::Name::Name(std::list<boost::reference_wrapper<const std::basic_string<char, std::char_traits<char>, std::allocator<char> > >,std::allocator<boost::reference_wrapper<const std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > const & components) [constructor]
-    cls.add_constructor([param('std::list< boost::reference_wrapper< std::string const > > const &', 'components')])
     ## ndn-name.h (module 'ndnSIM'): ns3::ndn::Name::Name(std::list<std::string, std::allocator<std::string> > const & components) [constructor]
     cls.add_constructor([param('std::list< std::string > const &', 'components')])
     ## ndn-name.h (module 'ndnSIM'): ns3::ndn::Name::Name(std::string const & prefix) [constructor]
@@ -6050,12 +6081,13 @@
     ## ndn-api-face.h (module 'ndnSIM'): void ns3::ndn::ApiFace::Shutdown() [member function]
     cls.add_method('Shutdown', 
                    'void', 
-                   [])
-    ## ndn-api-face.h (module 'ndnSIM'): void ns3::ndn::ApiFace::ExpressInterest(ns3::Ptr<ns3::ndn::Interest> interest, ns3::Callback<void,ns3::Ptr<const ns3::ndn::Interest>,ns3::Ptr<const ns3::ndn::ContentObject>,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty> onData, ns3::Callback<void,ns3::Ptr<const ns3::ndn::Interest>,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty> onTimeout) [member function]
+                   [], 
+                   is_virtual=True)
+    ## ndn-api-face.h (module 'ndnSIM'): void ns3::ndn::ApiFace::ExpressInterest(ns3::Ptr<ns3::ndn::Interest> interest, ns3::Callback<void, ns3::Ptr<ns3::ndn::Interest const>, ns3::Ptr<ns3::ndn::ContentObject const>, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> onData, ns3::Callback<void, ns3::Ptr<ns3::ndn::Interest const>, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> onTimeout) [member function]
     cls.add_method('ExpressInterest', 
                    'void', 
                    [param('ns3::Ptr< ns3::ndn::Interest >', 'interest'), param('ns3::Callback< void, ns3::Ptr< ns3::ndn::Interest const >, ns3::Ptr< ns3::ndn::ContentObject const >, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'onData'), param('ns3::Callback< void, ns3::Ptr< ns3::ndn::Interest const >, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'onTimeout')])
-    ## ndn-api-face.h (module 'ndnSIM'): void ns3::ndn::ApiFace::SetInterestFilter(ns3::Ptr<ns3::ndn::Name const> prefix, ns3::Callback<void,ns3::Ptr<const ns3::ndn::Name>,ns3::Ptr<const ns3::ndn::Interest>,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty> onInterest) [member function]
+    ## ndn-api-face.h (module 'ndnSIM'): void ns3::ndn::ApiFace::SetInterestFilter(ns3::Ptr<ns3::ndn::Name const> prefix, ns3::Callback<void, ns3::Ptr<ns3::ndn::Name const>, ns3::Ptr<ns3::ndn::Interest const>, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> onInterest) [member function]
     cls.add_method('SetInterestFilter', 
                    'void', 
                    [param('ns3::Ptr< ns3::ndn::Name const >', 'prefix'), param('ns3::Callback< void, ns3::Ptr< ns3::ndn::Name const >, ns3::Ptr< ns3::ndn::Interest const >, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'onInterest')])
diff --git a/bindings/modulegen__gcc_LP64.py b/bindings/modulegen__gcc_LP64.py
index 4255339..76287f8 100644
--- a/bindings/modulegen__gcc_LP64.py
+++ b/bindings/modulegen__gcc_LP64.py
@@ -210,6 +210,8 @@
     module.add_class('BooleanChecker', import_from_module='ns.core', parent=root_module['ns3::AttributeChecker'])
     ## boolean.h (module 'core'): ns3::BooleanValue [class]
     module.add_class('BooleanValue', import_from_module='ns.core', parent=root_module['ns3::AttributeValue'])
+    ## callback-based-app.h (module 'ndnSIM'): ns3::CallbackBasedApp [class]
+    module.add_class('CallbackBasedApp', parent=root_module['ns3::Application'])
     ## callback.h (module 'core'): ns3::CallbackChecker [class]
     module.add_class('CallbackChecker', import_from_module='ns.core', parent=root_module['ns3::AttributeChecker'])
     ## callback.h (module 'core'): ns3::CallbackImplBase [class]
@@ -381,8 +383,8 @@
     ## ndn-app-face.h (module 'ndnSIM'): ns3::ndn::AppFace [class]
     module.add_class('AppFace', parent=root_module['ns3::ndn::Face'])
     module.add_container('std::vector< ns3::Ptr< ns3::ndn::Face > >', 'ns3::Ptr< ns3::ndn::Face >', container_type='vector')
-    module.add_container('std::list< boost::reference_wrapper< std::string const > >', 'boost::reference_wrapper< std::basic_string< char, std::char_traits< char >, std::allocator< char > > const >', container_type='list')
     module.add_container('std::list< std::string >', 'std::string', container_type='list')
+    module.add_container('std::list< boost::reference_wrapper< std::string const > >', 'boost::reference_wrapper< std::basic_string< char, std::char_traits< char >, std::allocator< char > > const >', container_type='list')
     typehandlers.add_type_alias('ns3::ndn::ContentObject', 'ns3::ndn::ContentObjectHeader')
     typehandlers.add_type_alias('ns3::ndn::ContentObject*', 'ns3::ndn::ContentObjectHeader*')
     typehandlers.add_type_alias('ns3::ndn::ContentObject&', 'ns3::ndn::ContentObjectHeader&')
@@ -563,6 +565,7 @@
     register_Ns3AttributeValue_methods(root_module, root_module['ns3::AttributeValue'])
     register_Ns3BooleanChecker_methods(root_module, root_module['ns3::BooleanChecker'])
     register_Ns3BooleanValue_methods(root_module, root_module['ns3::BooleanValue'])
+    register_Ns3CallbackBasedApp_methods(root_module, root_module['ns3::CallbackBasedApp'])
     register_Ns3CallbackChecker_methods(root_module, root_module['ns3::CallbackChecker'])
     register_Ns3CallbackImplBase_methods(root_module, root_module['ns3::CallbackImplBase'])
     register_Ns3CallbackValue_methods(root_module, root_module['ns3::CallbackValue'])
@@ -3634,6 +3637,36 @@
                    [param('bool', 'value')])
     return
 
+def register_Ns3CallbackBasedApp_methods(root_module, cls):
+    ## callback-based-app.h (module 'ndnSIM'): ns3::CallbackBasedApp::CallbackBasedApp(ns3::CallbackBasedApp const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::CallbackBasedApp const &', 'arg0')])
+    ## callback-based-app.h (module 'ndnSIM'): ns3::CallbackBasedApp::CallbackBasedApp() [constructor]
+    cls.add_constructor([])
+    ## callback-based-app.h (module 'ndnSIM'): static ns3::TypeId ns3::CallbackBasedApp::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## callback-based-app.h (module 'ndnSIM'): void ns3::CallbackBasedApp::SetOnStartCallback(ns3::Callback<void, ns3::Ptr<ns3::Application>, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> onStart) [member function]
+    cls.add_method('SetOnStartCallback', 
+                   'void', 
+                   [param('ns3::Callback< void, ns3::Ptr< ns3::Application >, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'onStart')])
+    ## callback-based-app.h (module 'ndnSIM'): void ns3::CallbackBasedApp::SetOnStopCallback(ns3::Callback<void, ns3::Ptr<ns3::Application>, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> onStart) [member function]
+    cls.add_method('SetOnStopCallback', 
+                   'void', 
+                   [param('ns3::Callback< void, ns3::Ptr< ns3::Application >, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'onStart')])
+    ## callback-based-app.h (module 'ndnSIM'): void ns3::CallbackBasedApp::StartApplication() [member function]
+    cls.add_method('StartApplication', 
+                   'void', 
+                   [], 
+                   visibility='protected', is_virtual=True)
+    ## callback-based-app.h (module 'ndnSIM'): void ns3::CallbackBasedApp::StopApplication() [member function]
+    cls.add_method('StopApplication', 
+                   'void', 
+                   [], 
+                   visibility='protected', is_virtual=True)
+    return
+
 def register_Ns3CallbackChecker_methods(root_module, cls):
     ## callback.h (module 'core'): ns3::CallbackChecker::CallbackChecker() [constructor]
     cls.add_constructor([])
@@ -5629,8 +5662,6 @@
     cls.add_constructor([param('ns3::ndn::Name const &', 'arg0')])
     ## ndn-name.h (module 'ndnSIM'): ns3::ndn::Name::Name() [constructor]
     cls.add_constructor([])
-    ## ndn-name.h (module 'ndnSIM'): ns3::ndn::Name::Name(std::list<boost::reference_wrapper<const std::basic_string<char, std::char_traits<char>, std::allocator<char> > >,std::allocator<boost::reference_wrapper<const std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > const & components) [constructor]
-    cls.add_constructor([param('std::list< boost::reference_wrapper< std::string const > > const &', 'components')])
     ## ndn-name.h (module 'ndnSIM'): ns3::ndn::Name::Name(std::list<std::string, std::allocator<std::string> > const & components) [constructor]
     cls.add_constructor([param('std::list< std::string > const &', 'components')])
     ## ndn-name.h (module 'ndnSIM'): ns3::ndn::Name::Name(std::string const & prefix) [constructor]
@@ -6050,12 +6081,13 @@
     ## ndn-api-face.h (module 'ndnSIM'): void ns3::ndn::ApiFace::Shutdown() [member function]
     cls.add_method('Shutdown', 
                    'void', 
-                   [])
-    ## ndn-api-face.h (module 'ndnSIM'): void ns3::ndn::ApiFace::ExpressInterest(ns3::Ptr<ns3::ndn::Interest> interest, ns3::Callback<void,ns3::Ptr<const ns3::ndn::Interest>,ns3::Ptr<const ns3::ndn::ContentObject>,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty> onData, ns3::Callback<void,ns3::Ptr<const ns3::ndn::Interest>,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty> onTimeout) [member function]
+                   [], 
+                   is_virtual=True)
+    ## ndn-api-face.h (module 'ndnSIM'): void ns3::ndn::ApiFace::ExpressInterest(ns3::Ptr<ns3::ndn::Interest> interest, ns3::Callback<void, ns3::Ptr<ns3::ndn::Interest const>, ns3::Ptr<ns3::ndn::ContentObject const>, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> onData, ns3::Callback<void, ns3::Ptr<ns3::ndn::Interest const>, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> onTimeout) [member function]
     cls.add_method('ExpressInterest', 
                    'void', 
                    [param('ns3::Ptr< ns3::ndn::Interest >', 'interest'), param('ns3::Callback< void, ns3::Ptr< ns3::ndn::Interest const >, ns3::Ptr< ns3::ndn::ContentObject const >, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'onData'), param('ns3::Callback< void, ns3::Ptr< ns3::ndn::Interest const >, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'onTimeout')])
-    ## ndn-api-face.h (module 'ndnSIM'): void ns3::ndn::ApiFace::SetInterestFilter(ns3::Ptr<ns3::ndn::Name const> prefix, ns3::Callback<void,ns3::Ptr<const ns3::ndn::Name>,ns3::Ptr<const ns3::ndn::Interest>,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty> onInterest) [member function]
+    ## ndn-api-face.h (module 'ndnSIM'): void ns3::ndn::ApiFace::SetInterestFilter(ns3::Ptr<ns3::ndn::Name const> prefix, ns3::Callback<void, ns3::Ptr<ns3::ndn::Name const>, ns3::Ptr<ns3::ndn::Interest const>, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> onInterest) [member function]
     cls.add_method('SetInterestFilter', 
                    'void', 
                    [param('ns3::Ptr< ns3::ndn::Name const >', 'prefix'), param('ns3::Callback< void, ns3::Ptr< ns3::ndn::Name const >, ns3::Ptr< ns3::ndn::Interest const >, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'onInterest')])
diff --git a/model/ndn-content-object.cc b/model/ndn-content-object.cc
index 582ebc9..81d92f0 100644
--- a/model/ndn-content-object.cc
+++ b/model/ndn-content-object.cc
@@ -35,6 +35,10 @@
   , m_payload (payload)
   , m_wire (0)
 {
+  if (m_payload == 0) // just in case
+    {
+      m_payload = Create<Packet> ();
+    }
 }
 
 ContentObject::ContentObject (const ContentObject &other)
diff --git a/model/ndn-content-object.h b/model/ndn-content-object.h
index f586c15..6fa60dd 100644
--- a/model/ndn-content-object.h
+++ b/model/ndn-content-object.h
@@ -22,57 +22,19 @@
 #ifndef _NDN_CONTENT_OBJECT_HEADER_H_
 #define _NDN_CONTENT_OBJECT_HEADER_H_
 
-#include "ns3/integer.h"
-#include "ns3/header.h"
 #include "ns3/simple-ref-count.h"
-#include "ns3/trailer.h"
 #include "ns3/nstime.h"
 #include "ns3/packet.h"
+#include "ns3/ptr.h"
 
-#include <string>
-#include <vector>
-#include <list>
-
-#include "ndn-name.h"
+#include <ns3/ndn-name.h>
 
 namespace ns3 {
 namespace ndn {
 
 /**
- * ContentObject header
- *
- * Only few important fields are actually implemented in the simulation
- *
- * @see http://ndnsim.net/new-packet-formats.html
- *
- * Optimized and simplified formatting of Interest packets
- *
- *	ContentObject ::= Signature
- *                	  Name
- *                   	  Content
- *
- *      0                   1                   2                   3
- *      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- *      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *      |            Length             |                               |
- *      |-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
- *      ~                                                               ~
- *      ~                           Signature                           ~
- *      |							        |	
- *      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *      |            Length             |                               |
- *      |-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
- *      ~                                                               ~
- *      ~                             Name                              ~
- *      |							        |	
- *      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *      |            Length             |                               |
- *      |-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
- *      ~                                                               ~
- *      ~                           Content                             ~
- *      |							        |	
- *      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
+ * @ingroup Ndn
+ * @brief ContentObject header
  */
 class ContentObject : public SimpleRefCount<ContentObject>
 {
diff --git a/model/ndn-face.cc b/model/ndn-face.cc
index 5f8d75c..3681ffb 100644
--- a/model/ndn-face.cc
+++ b/model/ndn-face.cc
@@ -121,7 +121,7 @@
 bool
 Face::SendInterest (Ptr<const Interest> interest)
 {
-  NS_LOG_FUNCTION (this << interest);
+  NS_LOG_FUNCTION (this << boost::cref (*this) << interest->GetName ());
 
   if (!IsUp ())
     {
diff --git a/model/ndn-interest.cc b/model/ndn-interest.cc
index ffcaa0d..134cd01 100644
--- a/model/ndn-interest.cc
+++ b/model/ndn-interest.cc
@@ -38,6 +38,10 @@
   , m_payload (payload)
   , m_wire (0)
 {
+  if (m_payload == 0) // just in case
+    {
+      m_payload = Create<Packet> ();
+    }
 }
 
 Interest::Interest (const Interest &interest)
diff --git a/model/ndn-interest.h b/model/ndn-interest.h
index 32dfcd8..d0959a9 100644
--- a/model/ndn-interest.h
+++ b/model/ndn-interest.h
@@ -22,17 +22,12 @@
 #ifndef _NDN_INTEREST_HEADER_H_
 #define _NDN_INTEREST_HEADER_H_
 
-#include "ns3/integer.h"
-#include "ns3/header.h"
 #include "ns3/simple-ref-count.h"
 #include "ns3/nstime.h"
 #include "ns3/packet.h"
+#include "ns3/ptr.h"
 
-#include <string>
-#include <vector>
-#include <list>
-
-#include "ndn-name.h"
+#include <ns3/ndn-name.h>
 
 namespace ns3 {
 
diff --git a/model/ndn-name.cc b/model/ndn-name.cc
index 083d3d8..60d1b82 100644
--- a/model/ndn-name.cc
+++ b/model/ndn-name.cc
@@ -38,13 +38,13 @@
 {
 }
 
-Name::Name (const std::list<boost::reference_wrapper<const std::string> > &components)
-{
-  BOOST_FOREACH (const boost::reference_wrapper<const std::string> &component, components)
-    {
-      Add (component.get ());
-    }
-}
+// Name::Name (const std::list<boost::reference_wrapper<const std::string> > &components)
+// {
+//   BOOST_FOREACH (const boost::reference_wrapper<const std::string> &component, components)
+//     {
+//       Add (component.get ());
+//     }
+// }
 
 Name::Name (const std::list<std::string> &components)
 {
diff --git a/model/ndn-name.h b/model/ndn-name.h
index d69a75e..3eb2021 100644
--- a/model/ndn-name.h
+++ b/model/ndn-name.h
@@ -58,12 +58,12 @@
    */
   Name ();
 
-  /**
-   * \brief Constructor
-   * Creates a prefix from a list of strings where every string represents a prefix component
-   * @param[in] components A list of strings
-   */
-  Name (const std::list<boost::reference_wrapper<const std::string> > &components);
+  // /**
+  //  * \brief Constructor
+  //  * Creates a prefix from a list of strings where every string represents a prefix component
+  //  * @param[in] components A list of strings
+  //  */
+  // Name (const std::list<boost::reference_wrapper<const std::string> > &components);
 
   /**
    * \brief Constructor
diff --git a/model/wire/ndnsim.h b/model/wire/ndnsim.h
index c42e532..b46dba9 100644
--- a/model/wire/ndnsim.h
+++ b/model/wire/ndnsim.h
@@ -91,6 +91,40 @@
   Ptr<ndn::Interest> m_interest;
 };
 
+/**
+ * @brief Routines to serialize/deserialize Data packet in ndnSIM format
+ *
+ * Only few important fields are actually implemented in the simulation
+ *
+ * @see http://ndnsim.net/new-packet-formats.html
+ *
+ *	ContentObject ::= Signature
+ *                	  Name
+ *                   	  Content
+ *
+ *      0                   1                   2                   3
+ *      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ *      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *      |            Length             |                               |
+ *      |-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
+ *      ~                                                               ~
+ *      ~                           Signature                           ~
+ *      |							        |	
+ *      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *      |            Length             |                               |
+ *      |-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
+ *      ~                                                               ~
+ *      ~                             Name                              ~
+ *      |							        |	
+ *      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *      |            Length             |                               |
+ *      |-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
+ *      ~                                                               ~
+ *      ~                           Content                             ~
+ *      |							        |	
+ *      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
 class Data : public Header
 {
 public:
diff --git a/ndn.cxx/detail/timeouts-policy.h b/ndn.cxx/detail/timeouts-policy.h
index 7398d44..26d0c0f 100644
--- a/ndn.cxx/detail/timeouts-policy.h
+++ b/ndn.cxx/detail/timeouts-policy.h
@@ -145,7 +145,8 @@
       inline void
       ProcessTimeoutEntry (typename parent_trie::iterator item)
       {
-        item->payload ()->m_timeoutCallback (item->payload ()->GetInterest ());
+        if (!item->payload ()->m_timeoutCallback.IsNull ())
+          item->payload ()->m_timeoutCallback (item->payload ()->GetInterest ());
 
         m_base.erase (item);
       }
diff --git a/ndn.cxx/ndn-api-face.cc b/ndn.cxx/ndn-api-face.cc
index 6adfe99..578f424 100644
--- a/ndn.cxx/ndn-api-face.cc
+++ b/ndn.cxx/ndn-api-face.cc
@@ -186,8 +186,9 @@
     {
       return false;
     }
-  
-  entry->payload ()->m_callback (entry->payload ()->GetPrefix (), interest);
+
+  if (!entry->payload ()->m_callback.IsNull ())
+    entry->payload ()->m_callback (entry->payload ()->GetPrefix (), interest);
   return true;
 }
 
@@ -197,7 +198,6 @@
   // data has been send out from NDN stack towards the application
   NS_LOG_DEBUG ("<< D " << data->GetName ());
 
-
   NS_LOG_FUNCTION (this << data);
 
   if (!IsUp ())
@@ -213,7 +213,8 @@
 
   while (entry != m_this->m_pendingInterests.end ())
     {
-      entry->payload ()->m_dataCallback (entry->payload ()->GetInterest (), data);
+      if (!entry->payload ()->m_dataCallback.IsNull ())
+        entry->payload ()->m_dataCallback (entry->payload ()->GetInterest (), data);
       m_this->m_pendingInterests.erase (entry);
 
       entry = m_this->m_pendingInterests.longest_prefix_match (data->GetName ());
diff --git a/ndn.cxx/ndn-api-face.h b/ndn.cxx/ndn-api-face.h
index 160540e..4b88f51 100644
--- a/ndn.cxx/ndn-api-face.h
+++ b/ndn.cxx/ndn-api-face.h
@@ -28,6 +28,8 @@
 #include <ns3/callback.h>
 #include <ns3/ndn-face.h>
 #include <ns3/ndn-name.h>
+#include <ns3/ndn-interest.h>
+#include <ns3/ndn-content-object.h>
 
 namespace ns3 {
 namespace ndn {
@@ -58,7 +60,7 @@
   /**
    * @brief Shutdown the API face
    */
-  void
+  virtual void
   Shutdown ();
   
   /**
@@ -115,6 +117,15 @@
   ApiFacePriv *m_this;
 };
 
+
+/// @cond include_hidden
+#ifdef PYTHON_SCAN
+struct CallbackVoidNameInterest : public Callback<void, Ptr<const Name>, Ptr<const Interest> > { };
+struct CallbackVoidInterestContentObject : public Callback<void, Ptr<const Interest>, Ptr<const ContentObject> > { };
+struct CallbackVoidInterest : public Callback<void, Ptr<const Interest> > { };
+#endif
+/// @endcond
+
 }
 }
 
diff --git a/wscript b/wscript
index 9407508..eaa54c2 100644
--- a/wscript
+++ b/wscript
@@ -153,6 +153,7 @@
         "utils/ndn-rtt-estimator.h",
 
         "ndn.cxx/ndn-api-face.h",
+        "apps/callback-based-app.h",
         ]
 
     if 'topology' in bld.env['NDN_plugins']: