Commit 59950133 authored by garciay's avatar garciay
Browse files

Add beaconing based on POSIX timer, alternatively based on fork (commented code)

parent 2d3af265
Loading
Loading
Loading
Loading
+270 −17
Original line number Diff line number Diff line
@@ -7,6 +7,10 @@
// You may modify this file. Complete the body of empty functions and
// add your member functions here.

/*#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>*/

#include "GeoNetworkingPort.hh"
#include "GeoNetworkingLayer.hh"
#include "loggers.hh"
@@ -14,17 +18,21 @@
namespace LibItsGeoNetworking__TestSystem {

  GeoNetworkingPort::GeoNetworkingPort(const char *par_port_name)
    : GeoNetworkingPort_BASE(par_port_name), _cfg_params(), _layer_params(), _layer(NULL), _time_key("GeoNetworkingPort::outgoing_send")
  {

  }
    : GeoNetworkingPort_BASE(par_port_name), _cfg_params(), _layer_params(), _layer(NULL), _time_key("GeoNetworkingPort::outgoing_send") /*, _use_posix_timer(true), _child(-1), _child_pids{-1, -1}, _parent_pids{-1, -1}, _timerid{0}, _sev{0}, _its{0}, _freq_nanosecs(0), _mask{0}, _sa{0}*/ {
      // Nothing to do
  } // End of constructor
  
  GeoNetworkingPort::~GeoNetworkingPort()
  {
    loggers::get_instance().log(">>> GeoNetworkingPort::~GeoNetworkingPort");
    
    /*if (_use_posix_timer && (_timerid != 0)) {
      timer_delete(_timerid);
      }*/	
    if (_layer != NULL) {
      delete _layer;
    }
  }
  } // End of destructor

  void GeoNetworkingPort::set_parameter(const char * parameter_name, const char * parameter_value)
  {
@@ -58,37 +66,213 @@ namespace LibItsGeoNetworking__TestSystem {
    // Build layer stack
    Params::iterator it = _cfg_params.find(std::string("params"));
    if (it != _cfg_params.end()) {
      //loggers::get_instance().log("GeoNetworkingPort::user_map: %s", it->second.c_str());
      //loggers::get_instance().log("GeoNetworkingPort::user_map<%d>: %s", _child, it->second.c_str());
      // Setup parameters
      Params::convert(_layer_params, it->second);
      // Create layer
      _layer = LayerStackBuilder::GetInstance()->createLayerStack(it->second.c_str());
      if (static_cast<GeoNetworkingLayer *>(_layer) == NULL) {
	loggers::get_instance().error("GeoNetworkingPort::user_map: Invalid stack configuration: %s", it->second.c_str());
      }
      static_cast<GeoNetworkingLayer *>(_layer)->addUpperPort(this);

      /*if (_use_posix_timer) {	
	// Establish handler for timer signal
	loggers::get_instance().log("GeoNetworkingPort::user_map: Establishing handler for signal %d\n", SIGALRM);
	_sa.sa_flags = SA_SIGINFO;
	_sa.sa_sigaction = timer_irq_sigalrm_handler;
	sigemptyset(&_sa.sa_mask);
	if (sigaction(SIGALRM, &_sa, NULL) == -1) {
	  loggers::get_instance().error("GeoNetworkingPort::user_map: Sigaction failure: %d", errno);
	}
	// Block timer signal temporarily
	loggers::get_instance().log("GeoNetworkingPort::user_map: Blocking signal %d\n", SIGALRM);
	sigemptyset(&_mask);
	sigaddset(&_mask, SIGALRM);
	if (sigprocmask(SIG_SETMASK, &_mask, NULL) == -1) {
	  loggers::get_instance().error("GeoNetworkingPort::user_map: Sigprocmask failure: %d", errno);
	}	
	// Create the timer 
	_sev.sigev_notify = SIGEV_SIGNAL;
	_sev.sigev_signo = SIGALRM; // Use signal alarm
	_sev.sigev_value.sival_ptr = this; // The GeoNetworkingPort object address
	if (timer_create(CLOCK_REALTIME, &_sev, &_timerid) == -1) {
	  loggers::get_instance().error("GeoNetworkingPort::user_map: Timer failure: %d", errno);
	}
	loggers::get_instance().log("GeoNetworkingPort::user_map: timer ID is 0x%lx\n", (long)_timerid);
	// Start the timer
	unsigned int expiry = 1000; // One second
	Params::const_iterator i = _layer_params.find("expiry");
	if (i != _layer_params.cend()) {
	  expiry = static_cast<unsigned int>(std::strtoul(it->second.c_str(), NULL, 10));
	}
	_freq_nanosecs = 1000*1000000; // expiry time 1000ms
	_its.it_value.tv_sec = _freq_nanosecs / 1000000000;
	_its.it_value.tv_nsec = _freq_nanosecs % 1000000000;
	_its.it_interval.tv_sec = _its.it_value.tv_sec;
	_its.it_interval.tv_nsec = _its.it_value.tv_nsec;
	if (timer_settime(_timerid, 0, &_its, NULL) == -1) {
	  loggers::get_instance().error("GeoNetworkingPort::user_map: Sigprocmask failure: %d", errno);
	}
	// Unlock the timer signal, so that timer notification can be delivered
	loggers::get_instance().log("GeoNetworkingPort::user_map: Unblocking signal %d\n", SIGALRM);
	if (sigprocmask(SIG_UNBLOCK, &_mask, NULL) == -1) {
	  loggers::get_instance().error("GeoNetworkingPort::user_map: Sigprocmask failure: %d", errno);
	}
      }*/
      /*else { // _use_posix_timer
	// TODO If timer mechanism is enought, remove fork code
	if (_child > 0) { // Start beaconing if required
	  Params::const_iterator i = _layer_params.find(Params::beaconing);
	  if ((i != _layer_params.cend()) && (i->second.compare("1") == 0)) {  
	    unsigned char *buffer = new unsigned char[it->second.length() + 1];
	    buffer[0] = 0x01;
	    copy(it->second.begin(), it->second.end(), buffer + 1);
	    write(_child_pids[1], buffer, it->second.length() + 1);
	    bool ack = false;
	    while (!ack) {
	      if ((read(_parent_pids[0], buffer, 1) > 0) && (buffer[0] == 0xAA)) {
		loggers::get_instance().log("GeoNetworkingPort::user_map: Receive ack from child");
		ack = true;
	      }
	    } // End of 'while' statement
	    delete [] buffer;
	  } else {
      loggers::get_instance().error("GeoNetworkingPort::user_map: No layers defined in configuration file");
	    loggers::get_instance().log("GeoNetworkingPort::user_map: Beaconing not requested");
	  }

    //static_cast<GeoNetworkingLayer *>(_layer)->start_beaconing();
	} // else, in child process
	}*/
    } else {
      loggers::get_instance().error("GeoNetworkingPort::user_map: No layers defined in configuration file");
    }
  } // End of user_map method
  
  void GeoNetworkingPort::user_unmap(const char * system_port)
  {
    loggers::get_instance().log(">>> GeoNetworkingPort::user_unmap: %s", system_port);

    // Stop timer
    /*if (_use_posix_timer) {	
      // Block timer signal temporarily
      loggers::get_instance().log("GeoNetworkingPort::user_unmap: Blocking signal %d\n", SIGALRM);
      sigemptyset(&_mask);
      sigaddset(&_mask, SIGALRM);
      if (sigprocmask(SIG_SETMASK, &_mask, NULL) == -1) {
	loggers::get_instance().error("GeoNetworkingPort::user_map: Sigprocmask failure: %d", errno);
      }	
      timer_delete(_timerid);
      _timerid = 0;
      }*/
    // Reset layers
    if (_layer != NULL) {
      delete _layer;
      _layer = NULL;
    }
  }
  } // End of user_unmap method

  void GeoNetworkingPort::user_start()
  {
    loggers::get_instance().log(">>> GeoNetworkingPort::user_start");

    // TODO If timer mechanism is enought, remove fork code
    /*if (!_use_posix_timer) { // Use fork
      // Set up pipes for process communication
      if (pipe2(_parent_pids, O_NONBLOCK) != 0) { // Failed to create pipe
	loggers::get_instance().error("GeoNetworkingPort::user_start: Parent pipe creation failure: %d", errno);
      }
      if (pipe2(_child_pids, O_NONBLOCK) != 0) { // Failed to create pipe
	loggers::get_instance().error("GeoNetworkingPort::user_start: Child pipe creation failure: %d", errno);
      }
      
      // Fork port for beaconing beacause of TITAN is not multithread at all :-(
      // NOTE Need to fork process very early due to issues for handle dup operation
      _child = fork();
      if (_child == -1) { // Fork failure
	close(_parent_pids[0]);
	close(_parent_pids[1]);
	close(_child_pids[0]);
	close(_child_pids[1]);
	loggers::get_instance().error("GeoNetworkingPort::user_start: Fork failure: %d", errno);
      } else if (_child == 0) { // Child process
	loggers::get_instance().log("GeoNetworkingPort::user_start: Child process is running");
	// This is a hack
	// All fds (except the pipe) should be closed in order to avoid some "funny" communication lost between the mctr and PTC
	for (int i = 4; i < 128; i++) {
	  if (
	      (i != _parent_pids[0]) && (i != _parent_pids[1]) &&
	      (i != _child_pids[0]) && (i != _child_pids[1])
	      ) {
	    if (dup(i) == EBADF) {
	      loggers::get_instance().log("GeoNetworkingPort::user_start: Child dup stops at %d - _layer=%p", i, _layer);
	      break;
	    }
	  }
	} // End of 'for' statement
	// Close _child_pids[1], down channel
	close(_child_pids[1]);
	_child_pids[1] = -1;
	// Close _parent_pids[0], down channel
	close(_parent_pids[0]);
	_parent_pids[0] = -1;
	
	process_background();
	loggers::get_instance().log("GeoNetworkingPort::user_start: Child terminates");
	std::_Exit(EXIT_SUCCESS);
      } else { // Parent process
	loggers::get_instance().log("GeoNetworkingPort::user_start: Parent process is running");
	// Close _pids[0], up channel
	close(_child_pids[0]);
	_child_pids[0] = -1;
	// Close _parent_pids[1], down channel
	close(_parent_pids[1]);
	_parent_pids[1] = -1;
	unsigned char buffer[2];
	
	bool ack = false;
	while (!ack) {
	  if ((read(_parent_pids[0], buffer, 1) > 0) && (buffer[0] == 0xAA)) {
	    loggers::get_instance().log("GeoNetworkingPort::user_start: Receive ack from child");
	    ack = true;
	  }
	} // End of 'while' statement
      }
    } else {
      _child = -1;
    }*/
  } // End of user_start method

  void GeoNetworkingPort::user_stop()
  {
    loggers::get_instance().log(">>> GeoNetworkingPort::user_stop");

    // TODO If timer mechanism is enought, remove fork code
    /*if (_child > 0) { // Parent process
      // Terminate child process
      loggers::get_instance().log("GeoNetworkingPort::user_stop: Stopping child process");
      unsigned char buffer[] = { 0xFF };
      write(_child_pids[1], buffer, 1);
      // And wait for the child ack
      bool ack = false;
      while (!ack) {
	if ((read(_parent_pids[0], buffer, 1) > 0) && (buffer[0] == 0xAA)) {
	  loggers::get_instance().log("GeoNetworkingPort::user_stop: Receive ack from child");
	  ack = true;
	}
      } // End of 'while' statement
      // Wait child process
      int status = -1;
      waitpid(_child, &status, WNOHANG); // TODO Check returned code
      loggers::get_instance().log("GeoNetworkingPort::user_stop: Child process ended [%d]", status);
      // Close _parent_pids[1], up channel
      close(_parent_pids[0]);
      _parent_pids[0] = -1;
      // Close _pids[1], down channel
      close(_child_pids[1]);
      _child_pids[1] = -1;
      // Reset child pid
      _child = -1;
      }*/
  } // End of user_stop method

  void GeoNetworkingPort::outgoing_send(const GeoNetworkingReq& send_par)
  {
@@ -106,6 +290,10 @@ namespace LibItsGeoNetworking__TestSystem {
    if (!p_ind.is_bound()) {
      return;
    }
    // TODO If timer mechanism is enought, remove fork code
    /*if (_child == 0) { // Bacgound task processing, ignore it
      return;
    */

    // Update location table
    if (p_ind.msgIn().basicHeader().version() == 0) { // Non secured mode
@@ -129,5 +317,70 @@ namespace LibItsGeoNetworking__TestSystem {
    incoming_message(p_ind);
  }

  // TODO If timer mechanism is enought, remove fork code
  /*void GeoNetworkingPort::process_background() {
    loggers::get_instance().log(">>> GeoNetworkingPort::process_background");

    std::chrono::milliseconds expiry(1000); // Default is set to 1 second
    unsigned long long ms;
    unsigned char buffer[512];
    bool terminate = false;
    // Child process ready, send an ack (0xAA)
    buffer[0] = 0xAA;
    write(_parent_pids[1], buffer, 1);
    while (!terminate) {
      int result = read(_child_pids[0], buffer, 512);
      if (result > 0) {
	loggers::get_instance().log("GeoNetworkingPort::process_background: receive %d bytes", result);
	OCTETSTRING os(result, buffer); // TODO For debug, to be removed
	loggers::get_instance().log_to_hexa("GeoNetworkingPort::process_background: ", os);
	// Decode it
	switch (buffer[0]) {
	case 0x01:
	  {
	    std::string s((const char *)(buffer + 1), result - 1);
	    loggers::get_instance().log("GeoNetworkingPort::process_background: %s", s.c_str());
	    _layer = LayerStackBuilder::GetInstance()->createLayerStack(s.c_str());
	    static_cast<GeoNetworkingLayer *>(_layer)->addUpperPort(this);
	  }
	  break;
	case 0xFF:
	  terminate = true;
	  break;
	default:
	  // Discard it
	  break;
	} // End of 'switch' statement
	buffer[0] = 0xAA;
	write(_parent_pids[1], buffer, 1);
      }
      if (_layer != NULL) {
	static_cast<GeoNetworkingLayer *>(_layer)->send_beacon();	  
	// Timer
	ms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count() + expiry.count();
	loggers::get_instance().log("GeoNetworkingPort::process_background: Start timer: %ld", ms);
	while (ms > static_cast<unsigned long long>(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count()));
	loggers::get_instance().log("GeoNetworkingPort::process_background: After timer");
      }
    } // End of 'while' statement
    if (_layer != NULL) {
      delete _layer;
      _layer = NULL;
    }
    // Close _pids[1], up channel
    close(_child_pids[0]);
    _child_pids[0] = -1;
    // Close _parent_pids[1], down channel
    close(_parent_pids[1]);
    _parent_pids[1] = -1;
    
    loggers::get_instance().log("<<< GeoNetworkingPort::process_background");    } */// End of process_background method
  
/*void GeoNetworkingPort::timer_irq_sigalrm_handler(int sig, siginfo_t *si, void *uc) {
    loggers::get_instance().log("GeoNetworkingPort::timer_irq_sigalrm_handler: Caught signal %d\n", sig);

    static_cast<GeoNetworkingLayer *>(static_cast<GeoNetworkingPort *>(si->si_value.sival_ptr)->_layer)->send_beacon();
    }*/ // End of method timer_irq_sigalrm_handler
  
} /* end of namespace */
+20 −4
Original line number Diff line number Diff line
@@ -10,6 +10,10 @@
#ifndef GeoNetworkingPort_HH
#define GeoNetworkingPort_HH

/*#include <unistd.h>
#include <signal.h>
#include <time.h>*/

#include "LibItsGeoNetworking_TestSystem.hh"

#include "Layer.hh"
@@ -22,14 +26,22 @@ namespace LibItsGeoNetworking__TestSystem {
    Params _layer_params;
    Layer * _layer;
    std::string _time_key;
    /*pid_t _child;
    int _child_pids[2];
    int _parent_pids[2];*/
    /*bool _use_posix_timer; // TODO If timer mechanism is enought, remove fork code
    timer_t _timerid;
    struct sigevent _sev;
    struct itimerspec _its;
    long long _freq_nanosecs;
    sigset_t _mask;
    struct sigaction _sa;*/
    
  public:
    GeoNetworkingPort(const char *par_port_name = NULL);
    ~GeoNetworkingPort();

    void set_parameter(const char *parameter_name,
		       const char *parameter_value);

    void set_parameter(const char *parameter_name, const char *parameter_value);
    void receiveMsg (const LibItsGeoNetworking__TestSystem::GeoNetworkingInd&, const Params&);

  private:
@@ -39,6 +51,10 @@ namespace LibItsGeoNetworking__TestSystem {
    void Handle_Fd_Event_Writable(int fd);
    void Handle_Fd_Event_Readable(int fd);
    /* void Handle_Timeout(double time_since_last_call); */
    //void process_background(); TODO If timer mechanism is enought, remove fork code
    
    static void timer_irq_sigalrm_handler(int sig, siginfo_t *si, void *uc);   

  protected:
    void user_map(const char *system_port);
    void user_unmap(const char *system_port);
+85 −4
Original line number Diff line number Diff line
#include <thread>
#include <chrono>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>

#include "GeoNetworkingLayer.hh"
#include "GeoNetworkingTypes.hh"
@@ -7,8 +11,9 @@

using namespace LibItsGeoNetworking__TypesAndValues;

GeoNetworkingLayer::GeoNetworkingLayer(const std::string & p_type, const std::string & param) : TLayer<LibItsGeoNetworking__TestSystem::GeoNetworkingPort>(p_type), _params(), _codec(), _beacon(NULL), _sendData() {
GeoNetworkingLayer::GeoNetworkingLayer(const std::string & p_type, const std::string & param) : TLayer<LibItsGeoNetworking__TestSystem::GeoNetworkingPort>(p_type), _params(), _codec(), _beacon(NULL), _sendData(), _timerid{0}, _sev{0}, _its{0}, _freq_nanosecs(0), _mask{0}, _sa{0} {
  loggers::get_instance().log(">>> GeoNetworkingLayer::GeoNetworkingLayer: %s, %s", to_string().c_str(), param.c_str());
  
  // Setup parameters
  Params::convert(_params, param);
  // Sanity checks
@@ -33,10 +38,16 @@ GeoNetworkingLayer::GeoNetworkingLayer(const std::string & p_type, const std::st
    _params.insert(std::pair<std::string, std::string>(std::string("mac_bc"), "FFFFFFFFFFFF"));
  }
  fill_beacon(latitude, longitude, ll_address);
  Params::const_iterator i = _params.find(Params::beaconing);
  if ((i != _params.cend()) && (i->second.compare("1") == 0)) {
    start_beaconing();
  }
} // End of constructor

GeoNetworkingLayer::~GeoNetworkingLayer() {

  if (_timerid != 0) {
    timer_delete(_timerid);
  }	
} // End of destructor

void GeoNetworkingLayer::sendMsg(const LibItsGeoNetworking__TestSystem::GeoNetworkingReq& p, Params& params) {
@@ -103,8 +114,71 @@ void GeoNetworkingLayer::receiveData(OCTETSTRING& data, Params& params) {
  toAllUpperPorts(p, params);
}


void GeoNetworkingLayer::start_beaconing() {
  loggers::get_instance().log(">>> GeoNetworkingLayer::start_beaconing");
  
  // Establish handler for timer signal
  loggers::get_instance().log("GeoNetworkingLayer::start_beaconing: Establishing handler for signal %d\n", SIGALRM);
  _sa.sa_flags = SA_SIGINFO;
  _sa.sa_sigaction = timer_irq_sigalrm_handler;
  sigemptyset(&_sa.sa_mask);
  if (sigaction(SIGALRM, &_sa, NULL) == -1) {
    loggers::get_instance().error("GeoNetworkingLayer::start_beaconing: Sigaction failure: %d", errno);
  }
  // Block timer signal temporarily
  loggers::get_instance().log("GeoNetworkingLayer::start_beaconing: Blocking signal %d\n", SIGALRM);
  sigemptyset(&_mask);
  sigaddset(&_mask, SIGALRM);
  if (sigprocmask(SIG_SETMASK, &_mask, NULL) == -1) {
    loggers::get_instance().error("GeoNetworkingLayer::start_beaconing: Sigprocmask failure: %d", errno);
  }	
  // Create the timer 
  _sev.sigev_notify = SIGEV_SIGNAL;
  _sev.sigev_signo = SIGALRM; // Use signal alarm
  _sev.sigev_value.sival_ptr = this; // The GeoNetworkingLayer object address
  if (timer_create(CLOCK_REALTIME, &_sev, &_timerid) == -1) {
    loggers::get_instance().error("GeoNetworkingLayer::start_beaconing: Timer failure: %d", errno);
  }
  loggers::get_instance().log("GeoNetworkingLayer::start_beaconing: timer ID is 0x%lx\n", (long)_timerid);
  // Start the timer
  unsigned int expiry = 1000; // Default expiry time 1000ms
  Params::const_iterator i = _params.find("expiry");
  if (i != _params.cend()) {
    expiry = static_cast<unsigned int>(std::strtoul(i->second.c_str(), NULL, 10));
  }
  _freq_nanosecs = expiry * 1000000;
  _its.it_value.tv_sec = _freq_nanosecs / 1000000000;
  _its.it_value.tv_nsec = _freq_nanosecs % 1000000000;
  _its.it_interval.tv_sec = _its.it_value.tv_sec;
  _its.it_interval.tv_nsec = _its.it_value.tv_nsec;
  if (timer_settime(_timerid, 0, &_its, NULL) == -1) {
    loggers::get_instance().error("GeoNetworkingLayer::start_beaconing: Sigprocmask failure: %d", errno);
  }
  // Unlock the timer signal, so that timer notification can be delivered
  loggers::get_instance().log("GeoNetworkingLayer::start_beaconing: Unblocking signal %d\n", SIGALRM);
  if (sigprocmask(SIG_UNBLOCK, &_mask, NULL) == -1) {
    loggers::get_instance().error("GeoNetworkingLayer::start_beaconing: Sigprocmask failure: %d", errno);
  }
}

void GeoNetworkingLayer::stop_beaconing() {
  loggers::get_instance().log(">>> GeoNetworkingLayer::stop_beaconing");
  
  // Block timer signal temporarily
  loggers::get_instance().log("GeoNetworkingLayer::stop_beaconing: Blocking signal %d\n", SIGALRM);
  sigemptyset(&_mask);
  sigaddset(&_mask, SIGALRM);
  if (sigprocmask(SIG_SETMASK, &_mask, NULL) == -1) {
    loggers::get_instance().error("GeoNetworkingLayer::stop_beaconing: Sigprocmask failure: %d", errno);
  }	
  timer_delete(_timerid);
  _timerid = 0;
}

void GeoNetworkingLayer::send_beacon() {
  loggers::get_instance().log(">>> GeoNetworkingLayer::send_beacon");
  
  ExtendedHeader* eh = static_cast<ExtendedHeader *>(_beacon->gnPacket().packet().extendedHeader().get_opt_value());
  if (eh == NULL) {
    loggers::get_instance().error("GeoNetworkingLayer::send_beacon: Wrong cast");
@@ -185,6 +259,13 @@ void GeoNetworkingLayer::fill_beacon(INTEGER& p_latitude, INTEGER& p_longitude,
  //  loggers::get_instance().log_msg("GeoNetworkingLayer::GeoNetworkingLayer: beacon value: ", *p._beacon);
}

  
void GeoNetworkingLayer::timer_irq_sigalrm_handler(int p_signal, siginfo_t *p_signal_info, void *p_uc) {
  loggers::get_instance().log("GeoNetworkingLayer::timer_irq_sigalrm_handler: Caught signal %d\n", p_signal);

  static_cast<GeoNetworkingLayer *>(p_signal_info->si_value.sival_ptr)->send_beacon();
} // End of method timer_irq_sigalrm_handler

class GeoNetworkingFactory: public LayerFactory {
  static GeoNetworkingFactory _f;
public:
+15 −3
Original line number Diff line number Diff line
#ifndef GEONETWORKING_LAYER_H
#define GEONETWORKING_LAYER_H

#include <thread>
#include <unistd.h>
#include <signal.h>
#include <time.h>

#include <mutex>

#include "Layer.hh"
@@ -22,11 +25,18 @@ class GeoNetworkingLayer : public TLayer<LibItsGeoNetworking__TestSystem::GeoNet
  GeoNetworkingCodec _codec;
  LibItsGeoNetworking__TypesAndValues::GeoNetworkingPdu* _beacon;
  std::mutex _sendData; // FIXME To be removed, useless
  timer_t _timerid;
  struct sigevent _sev;
  struct itimerspec _its;
  long long _freq_nanosecs;
  sigset_t _mask;
  struct sigaction _sa;

  void fill_beacon(INTEGER& p_latitude, INTEGER& p_longitude, OCTETSTRING& p_ll_address);
  static void timer_irq_sigalrm_handler(int p_signal, siginfo_t *p_signal_info, void *p_uc);   

public:
  GeoNetworkingLayer() : TLayer<LibItsGeoNetworking__TestSystem::GeoNetworkingPort>(), _params(), _codec(), _beacon(NULL), _sendData() {};
  GeoNetworkingLayer() : TLayer<LibItsGeoNetworking__TestSystem::GeoNetworkingPort>(), _params(), _codec(), _beacon(NULL), _sendData(), _timerid{0}, _sev{0}, _its{0}, _freq_nanosecs(0), _mask{0}, _sa{0} { };
  GeoNetworkingLayer(const std::string& p_type, const std::string& param);
  virtual ~GeoNetworkingLayer();
  
@@ -35,6 +45,8 @@ public:
  virtual void sendData(OCTETSTRING& data, Params& params);
  virtual void receiveData(OCTETSTRING& data, Params& params);

  void start_beaconing();
  void stop_beaconing();
  void send_beacon();
};