Skip to content
This repository has been archived by the owner on Aug 25, 2020. It is now read-only.

Simple Application

Marvin Frick edited this page May 28, 2013 · 1 revision

Simple Application

After learning the fundamentals of application development, we create an own application step by step. It is assumed that the legacyapps folder has been successfully created and integrated into CMake configuration.

The application will be similar to the HelloWorld one in the apps directory. A node sends out exactly one message in the first simulation round. Neighbors receiving such a message add the sender to a private set of immediate neighbors, and print out a debug message. The example will also be extended by parameterized options and the possibility of data extraction later (see Paragraphs XXX and XXX).

Creating the Files

First, change to legacyapps and create a folder named simple_app. Then copy all files helloworld_processor* and helloworld_message.* from src/apps/examples/processor, as well as module.cmake and examples_init/* from src/apps/example to the new directory. Rename helloworld and examples to simple_app. The folder then contains the following files.

  module.cmake
  simple_app_init.h
  simple_app_init.cpp
  simple_app_message.h
  simple_app_message.cpp
  simple_app_processor.h
  simple_app_processor.cpp
  simple_app_processor_factory.h
  simple_app_processor_factory.cpp
Adapting the Source

You have to replace some strings in the *.h and *.cpp files.

Replace any occurrence of

  • helloworld with simple_app (and Helloworld with SimpleApp, respectively).
  • "_apps_enable_cmake.h" with "_legacyapps_enable_cmake.h"
  • ENABLE_EXAMPLES with ENABLE_SIMPLE_APP
  • apps/examples/processor with legacyapps/simple_app
  • EXAMPLES_PROCESSOR with LEGACYAPPS_SIMPLE_APP
  • EXAMPLETASK_EXAMPLETASK with SIMPLE_APP
  • init_examples with init_simple_app

The file module.cmake is changed in exactly one line:

  set ( moduleName SIMPLE_APP )

The simple_app_processor.cpp must be changed in more lines, and is thus completely presented:

/************************************************************************
 ** This file is part of the network simulator Shawn.                  **
 ** Copyright (C) 2004-2007 by the SwarmNet (www.swarmnet.de) project  **
 ** Shawn is free software; you can redistribute it and/or modify it   **
 ** under the terms of the BSD License. Refer to the shawn-licence.txt **
 ** file in the root of the Shawn source tree for further details.     **
 ************************************************************************/
#include "legacyapps/simple_app/simple_app_processor.h"
#ifdef ENABLE_SIMPLE_APP

#include "legacyapps/simple_app/simple_app_message.h"
#include "sys/simulation/simulation_controller.h"
#include "sys/node.h"
#include <iostream>


namespace simple_app
{
   SimpleAppProcessor::
   SimpleAppProcessor()
   {}
   // ----------------------------------------------------------------------
   SimpleAppProcessor::
   ~SimpleAppProcessor()
   {}
   // ----------------------------------------------------------------------
   void
   SimpleAppProcessor::
   boot( void )
      throw()
   {}
   // ----------------------------------------------------------------------
   bool
   SimpleAppProcessor::
   process_message( const shawn::ConstMessageHandle& mh ) 
      throw()
   {
      const SimpleAppMessage* msg = 
          dynamic_cast<const SimpleAppMessage*>( mh.get() );

      if( msg != NULL )
      { 
         if( owner() != msg->source() )
         { 
            neighbours_.insert( &msg->source() );
            INFO( logger(), "Received message from '" 
                            << msg->source().label() 
                            << "'" );
        
         }
         return true;
      }

      return Processor::process_message( mh );
   }
   // ----------------------------------------------------------------------
   void
   SimpleAppProcessor::
   work( void )
      throw()
   {
      // send message only in the first simulation round
      if ( simulation_round() == 0 )
      { 
         send( new SimpleAppMessage );
      }
   }
}
#endif

Also, the simple_app_init.cpp looks different.

/************************************************************************
 ** This file is part of the network simulator Shawn.                  **
 ** Copyright (C) 2004-2007 by the SwarmNet (www.swarmnet.de) project  **
 ** Shawn is free software; you can redistribute it and/or modify it   **
 ** under the terms of the BSD License. Refer to the shawn-licence.txt **
 ** file in the root of the Shawn source tree for further details.     **
 ************************************************************************/
#include "legacyapps/simple_app/simple_app_init.h"
#ifdef ENABLE_SIMPLE_APP

#include "legacyapps/simple_app/simple_app_processor_factory.h"

extern "C" void init_simple_app( shawn::SimulationController& sc )
{
   simple_app::SimpleAppProcessorFactory::register_factory( sc );
}

#endif
Understanding the Source

The generated source contains the minimum for developing an own processor that is able to send and receive messages. Let us look at the files one by one.

First, module.cmake contains the name of the new module to enable configuration by CMake. Change to shawn/buildfiles and run ccmake ../src. Set MODULE_LEGACYAPPS_SIMPLE_APP to ON.

Then, in the consequence that the processors are able to send and receive own messages, the files simple_app_message.* contain a new message type SimpleAppMessage derived from shawn::Message which in turn provides basic information about sent messages such as source node, size, and timestamp. The presented application uses only the source node of a message, and thus SimpleAppMessage does not get any additional members.

Next, the SimpleAppProcessor has been modified to be a simple version of the HelloWorld application. During boot(), it does nothing. When receiving a message of type SimpleAppMessage, it adds the source of the message to the list of known neighbors and prints a debug message that contains the label of the source. Finally, a message is only sent in the first simulation round. There is an appropriate check in the periodically called work()-method.

The SimpleAppProcessorFactory must also be available for the simulation. Therefore it implements shawn::ProcessorFactory which mainly provides methods name() and create(). The name is used for selecting certain processors when creating nodes. For example, if a configuration file contains the line processors=simple_app, then all available processor factories are searched for the name simple_app. If found, the method create() of the factory is called to create a processor that is assigned to a node (each node gets one).

At last, the implemented processor factory must be added to Shawn's processor factories so that the processor name simple_app can be found. This happens in file simple_app_init.cpp where the method register_factory is called which in turn is implemented in SimpleAppProcessorFactory. When enabling a module via CMake configuration, the method init_modulename (here: init_simple_app) is automatically called and must be implemented.

Compiling and Running

After the source code has been copied and adapted, and the application has been enabled in CMake configuration (setting MODULE_LEGACYAPPS_SIMPLE_APP to ON), Shawn can be compiled to contain the new processor. Therefore type make from shawn/buildfiles directory. When compilation finished, the new processor of type simple_app can be used.

Create a file simpleapp.conf with the following content.

  prepare_world edge_model=simple comm_model=disk_graph range=2
  rect_world width=10 height=10 count=100 processors=simple_app
  simulation max_iterations=10
  connectivity

Calling shawn -f simpleapp.conf results in the exexution shown in Figure XXX.

ext_shawn01.png ext_shawn02.png 'Running the Simple Application.'

The simulation runs exactly as expected. The nodes send a message in the first simulation round (iteration 0), and receive the messages from their neighbors in iteration 1. Then, the simulation runs up to iteration 9, because we set max_iterations to 10. In contrast to the HelloWorld application, the nodes do not deactivate themselves.

However, we created a very simple processor that only sends out one messsage in a fixed simulation round, and adds the source of a message to an internal neighbor list on reception, and also prints a debug message. The next step is to parameterize the application, followed by an example for data extraction.