GeoNetworkingLayer.cc 22 KB
Newer Older
1
#include <thread>
garciay's avatar
garciay committed
2
#include <chrono>
3
4
5
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
garciay's avatar
garciay committed
6

garciay's avatar
garciay committed
7
8
9
#include "GeoNetworkingLayer.hh"
#include "GeoNetworkingTypes.hh"

garciay's avatar
garciay committed
10
#include "registration.hh"
garciay's avatar
garciay committed
11
12
#include "loggers.hh"

garciay's avatar
garciay committed
13
14
using namespace LibItsGeoNetworking__TypesAndValues;

garciay's avatar
garciay committed
15
GeoNetworkingLayer::GeoNetworkingLayer(const std::string & p_type, const std::string & param) : TLayer<LibItsGeoNetworking__TestSystem::GeoNetworkingPort>(p_type), _params(), _codec(), _beacon(nullptr), _location_table(), _pass_beacon_table(), _sendData(), _timerid{0}, _sev{0}, _its{0}, _freq_nanosecs(0), _mask{0}, _sa{0} {
garciay's avatar
garciay committed
16
  loggers::get_instance().log(">>> GeoNetworkingLayer::GeoNetworkingLayer: %s, %s", to_string().c_str(), param.c_str());
17
  
garciay's avatar
garciay committed
18
19
  // Setup parameters
  Params::convert(_params, param);
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
  // Sanity checks
  INTEGER latitude;
  Params::const_iterator it = _params.find(Params::latitude);
  if (it != _params.cend()) {
    latitude = str2int(CHARSTRING(it->second.c_str()));
  }
  INTEGER longitude;
  it = _params.find(Params::longitude);
  if (it != _params.cend()) {
    longitude = str2int(CHARSTRING(it->second.c_str()));
  }
  OCTETSTRING ll_address;
  it = _params.find(Params::ll_address);
  if (it != _params.cend()) {
    ll_address = str2oct(CHARSTRING(it->second.c_str()));
  }
  // Add broadcast address if needed
  it = _params.find("mac_bc");
garciay's avatar
garciay committed
38
39
40
  if (it == _params.cend()) {
    _params.insert(std::pair<std::string, std::string>(std::string("mac_bc"), "FFFFFFFFFFFF"));
  }
garciay's avatar
garciay committed
41
42
43
44
  // Register this object for AdapterControlPort
  loggers::get_instance().log("GeoNetworkingLayer::GeoNetworkingLayer: register %s/%p", p_type.c_str(), this);
  registration<GeoNetworkingLayer>::get_instance().add_item(p_type, this);
  
45
  Params::const_iterator i = _params.find(Params::beaconing);
garciay's avatar
garciay committed
46
  if ((i != _params.cend()) && (i->second.compare("1") == 0)) { // Immediate beaconing was requested
garciay's avatar
garciay committed
47
48
    // Prepare beaconing operation
    fill_beacon(latitude, longitude, ll_address);
49
50
    start_beaconing();
  }
51
 } // End of constructor
52

garciay's avatar
garciay committed
53
GeoNetworkingLayer::~GeoNetworkingLayer() {
garciay's avatar
garciay committed
54
55
  loggers::get_instance().log(">>> GeoNetworkingLayer::~GeoNetworkingLayer");

56
57
  if (_timerid != 0) {
    timer_delete(_timerid);
garciay's avatar
garciay committed
58
59
60
61
62
  }

  if (_beacon != nullptr) {
    delete _beacon;
  }
63
64
} // End of destructor

garciay's avatar
garciay committed
65
void GeoNetworkingLayer::sendMsg(const LibItsGeoNetworking__TestSystem::GeoNetworkingReq& p, Params& params) {
garciay's avatar
garciay committed
66
  loggers::get_instance().log(">>> GeoNetworkingLayer::sendMsg");
garciay's avatar
garciay committed
67
68

  // Encode GeoNetworking PDU
garciay's avatar
garciay committed
69
70
  OCTETSTRING data;
  _codec.encode(p.msgOut(), data);
garciay's avatar
garciay committed
71
  sendData(data, params);
garciay's avatar
garciay committed
72
73
}

garciay's avatar
garciay committed
74
void GeoNetworkingLayer::sendData(OCTETSTRING& data, Params& params) {
garciay's avatar
garciay committed
75
  loggers::get_instance().log_msg(">>> GeoNetworkingLayer::sendData: ", data);
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
  //params.log();

  // TODO Take into account the Security
  Params::const_iterator it = params.find(Params::packetize);
  /*if (it != params.cend()) {
    LibItsGeoNetworking__TypesAndValues::GeoNetworkingPacket gnp;
    if (_params[Params::btp_type].compare("btpA") == 0) {
      header.btpAHeader() = LibItsGeoNetworking__TypesAndValues::GeoNetworkingAHeader(
                                                                  std::stoi(_params[Params::btp_destination_port]),
                                                                  std::stoi(_params[Params::btp_info])
                                                                  );
    } else {
      header.btpBHeader() = LibItsGeoNetworking__TypesAndValues::GeoNetworkingBHeader(
                                                                  std::stoi(_params[Params::btp_destination_port]),
                                                                  std::stoi(_params[Params::btp_info])
                                                                  );
    }
    LibItsGeoNetworking__TypesAndValues::GeoNetworkingPacket p(
                                                               LibItsGeoNetworking__TypesAndValues::BasicHeader(
                                                                                                                1,
                                                                                                                LibItsGeoNetworking__TypesAndValues::BasicNextHeader(LibItsGeoNetworking__TypesAndValues::BasicNextHeader::e__commonHeader), // TODO Take into acount the Security
                                                                                                                0,
                                                                                                                LibItsGeoNetworking__TypesAndValues::Lifetime(
                                                                                                                                                              LibItsGeoNetworking__TypesAndValues::Ltbase(LibItsGeoNetworking__TypesAndValues::Ltbase::e__50ms),
                                                                                                                                                              std::stoi(_params[Params::expity]) / 50
                                                                                                                                                              ),
                                                                                                                10
),
                                                               LibItsGeoNetworking__TypesAndValues::GeoNetworkingPacket(gnp)
                                                               );
    loggers::get_instance().log_msg("GeoNetworkingLayer::sendData: ", p);
    
    // Encode GeoNetworking PDU
    OCTETSTRING os;
    _codec.encode(p, os);
    data = os;
    }*/
  
  // TODO To be removed
115
116
117
118
  while (_sendData.try_lock() == FALSE) {
    // not ready yet
    std::this_thread::sleep_for(std::chrono::milliseconds(1));
  } // End of 'while' statement
garciay's avatar
garciay committed
119
  sendToAllLayers(data, params);
120
121
  _sendData.unlock();
  loggers::get_instance().log("<<< GeoNetworkingLayer::sendData");
garciay's avatar
garciay committed
122
123
}

garciay's avatar
garciay committed
124
void GeoNetworkingLayer::receiveData(OCTETSTRING& data, Params& params) { 
garciay's avatar
garciay committed
125
  loggers::get_instance().log_msg(">>> GeoNetworkingLayer::receiveData: ", data);
garciay's avatar
garciay committed
126
  // Decode the payload
garciay's avatar
garciay committed
127
128
129
130
131
132
133
134
135
136
137
  LibItsGeoNetworking__TestSystem::GeoNetworkingInd ind;
  _codec.decode(data, ind.msgIn(), &params);
  
  // Update GeoNetworking layer
  if (ind.msgIn().basicHeader().version() == 0) { // Non secured mode
    const LibItsGeoNetworking__TypesAndValues::LongPosVector* sopv = nullptr;
    const LibItsGeoNetworking__TypesAndValues::GnNonSecuredPacket& p = ind.msgIn().gnPacket().packet();
    const LibItsGeoNetworking__TypesAndValues::HeaderTST& htst = p.commonHeader().headerTST();
    if (p.extendedHeader().ispresent()) { // Update location table
      const LibItsGeoNetworking__TypesAndValues::ExtendedHeader& ex = p.extendedHeader();    
      if (htst.ischosen(LibItsGeoNetworking__TypesAndValues::HeaderTST::ALT_beaconHdr)) { // Receive a beacon
garciay's avatar
garciay committed
138
        sopv = &ex.beaconHeader().srcPosVector();
garciay's avatar
garciay committed
139
      } else if (htst.ischosen(LibItsGeoNetworking__TypesAndValues::HeaderTST::ALT_tsbHdr)) { // Receive a topologicallyScopeBroadcast
garciay's avatar
garciay committed
140
141
142
143
144
        if (ex.ischosen(LibItsGeoNetworking__TypesAndValues::ExtendedHeader::ALT_tsbHeader)) {
          sopv = &ex.tsbHeader().srcPosVector();
        } else {
          sopv = &ex.shbHeader().srcPosVector();
        }
garciay's avatar
garciay committed
145
      } else if (htst.ischosen(LibItsGeoNetworking__TypesAndValues::HeaderTST::ALT_geoBroadcastHdr)) {
garciay's avatar
garciay committed
146
        sopv = &ex.geoBroadcastHeader().srcPosVector();
garciay's avatar
garciay committed
147
      } else if (htst.ischosen(LibItsGeoNetworking__TypesAndValues::HeaderTST::ALT_lsHdr)) { // Receive a location service
garciay's avatar
garciay committed
148
149
150
        if (ex.ischosen(LibItsGeoNetworking__TypesAndValues::ExtendedHeader::ALT_lsRequestHeader)) { // Receive a LocationService/LsRequest
          sopv = &ex.lsRequestHeader().srcPosVector();
          // TODO Send LsReply if we are not in context of GN ATS
garciay's avatar
garciay committed
151
152

	    
garciay's avatar
garciay committed
153
154
155
156
157
        } else {
          sopv = &ex.lsReplyHeader().srcPosVector();
        }
      } else if (htst.ischosen(LibItsGeoNetworking__TypesAndValues::HeaderTST::ALT_geoAnycastHdr)) { // Receive a GeoAnycast
        sopv = &ex.geoAnycastHeader().srcPosVector();
garciay's avatar
garciay committed
158
      } else if (htst.ischosen(LibItsGeoNetworking__TypesAndValues::HeaderTST::ALT_geoUnicastHdr)) {
garciay's avatar
garciay committed
159
160
161
162
163
164
165
166
167
        sopv = &ex.geoUnicastHeader().srcPosVector();
        /*} else if (htst.ischosen(LibItsGeoNetworking__TypesAndValues::HeaderTST::ALT_saHdr)) { // Receive Service Advertisement
          if (ex.ischosen(LibItsGeoNetworking__TypesAndValues::ExtendedHeader::ALT_xxx)) {
          sopv = &ex.xxxHeader().srcPosVector();
          } else {
          sopv = &ex.xxxHeader().srcPosVector();
          }*/
      } // else, nothing to do
      loggers::get_instance().log("GeoNetworkingLayer::receiveData: sopv is boud: %d", sopv->is_bound());
garciay's avatar
garciay committed
168
      if(sopv->is_bound()) {
garciay's avatar
garciay committed
169
170
        const LibItsGeoNetworking__TypesAndValues::LongPosVector& lpv = *sopv;
        _location_table.add_entry(lpv);
garciay's avatar
garciay committed
171
172
173
174
      }
    }
    
    // By default incoming beacons are filtered by the test adapter
garciay's avatar
garciay committed
175
176
177
178
179
180
181
182
183
184
185
186
187
    if (htst.ischosen(LibItsGeoNetworking__TypesAndValues::HeaderTST::ALT_beaconHdr)) {
      loggers::get_instance().log_msg("GeoNetworkingLayer::receiveData: Pass beaconing processing", htst);
      if (_pass_beacon_table.empty()) { // Discard beacon
        loggers::get_instance().log("GeoNetworkingLayer::receiveData: Pass beaconing table empty, skip it");
        return;
      } else { // TODO Add beacon filter for StartPassBeaconing/Stop
        if (!_pass_beacon_table.has_entry(sopv->gnAddr().mid())) { // Discard beacon
          loggers::get_instance().log_msg("GeoNetworkingLayer::receiveData: Not in pass beaconing table, skip it", *sopv);
          return;
        } // else, continue
      }
    } // else, continue
  } // TODO else security mode, becarefull to duplicate code
garciay's avatar
garciay committed
188

garciay's avatar
garciay committed
189
  // Add lower layers parameters
garciay's avatar
garciay committed
190
  // 1. Destination MAC address
garciay's avatar
garciay committed
191
  Params::const_iterator it = params.find(Params::mac_dst);
garciay's avatar
garciay committed
192
  if (it != params.cend()) {
193
    loggers::get_instance().log("GeoNetworkingLayer::receiveData: dst=%s", it->second.c_str());
garciay's avatar
garciay committed
194
    ind.macDestinationAddress() = str2oct(CHARSTRING(it->second.c_str()));
garciay's avatar
garciay committed
195
  } else {
garciay's avatar
garciay committed
196
    ind.macDestinationAddress() = str2oct(CHARSTRING(_params["mac_bc"].c_str()));
garciay's avatar
garciay committed
197
198
199
200
  }
  // 2. ssp
  it = params.find(Params::ssp);
  if (it != params.cend()) {
201
    loggers::get_instance().log("GeoNetworkingLayer::receiveData: ssp=%s", it->second.c_str());
garciay's avatar
garciay committed
202
    ind.ssp() = str2bit(CHARSTRING(it->second.c_str()));
garciay's avatar
garciay committed
203
  } else {
garciay's avatar
garciay committed
204
    ind.ssp().set_to_omit();
garciay's avatar
garciay committed
205
  }
garciay's avatar
garciay committed
206
207
208
  // 3. its_aid
  it = params.find(Params::its_aid);
  if (it != params.cend()) {
209
    loggers::get_instance().log("GeoNetworkingLayer::receiveData: its_aid=%s", it->second.c_str());
garciay's avatar
garciay committed
210
    ind.its__aid() = std::stoi(it->second.c_str());
garciay's avatar
garciay committed
211
  } else {
garciay's avatar
garciay committed
212
    ind.its__aid().set_to_omit();
garciay's avatar
garciay committed
213
214
  }
  
215
216
217
218
219
220
221
222
223
224
  // Pass the GeoNetworking raw payload to the upper layers if any
  it = params.find(Params::gn_payload);
  if (it != params.cend()) {
    loggers::get_instance().log("GeoNetworkingLayer::receiveData: gn_payload=%s", it->second.c_str());
    OCTETSTRING os(str2oct(CHARSTRING(it->second.c_str())));
    receiveToAllLayers(os, params);
  } else {
    loggers::get_instance().warning("GeoNetworkingLayer::receiveData: No payload to pass to upper layers");
  }
  // Pass it to the ports
garciay's avatar
garciay committed
225
  toAllUpperPorts(ind, params);
garciay's avatar
garciay committed
226
227
}

garciay's avatar
garciay committed
228
229
230
231
232
233
234
235
OCTETSTRING GeoNetworkingLayer::trigger_ac_event(OCTETSTRING& data, Params& params)
{
  loggers::get_instance().log_to_hexa(">>> GeoNetworkingLayer::trigger_ac_event: ", data);


  return int2oct(0, 2);  
} // End of trigger_ac_event method

236
237
void GeoNetworkingLayer::start_beaconing() {
  loggers::get_instance().log(">>> GeoNetworkingLayer::start_beaconing");
garciay's avatar
garciay committed
238
239
  loggers::get_instance().log_msg("GeoNetworkingLayer::start_beaconing: _beacon=", *_beacon);

240
  // Establish handler for timer signal
garciay's avatar
garciay committed
241
  loggers::get_instance().log("GeoNetworkingLayer::start_beaconing: Establishing handler for signal %d\n", _signal_id);
242
243
244
  _sa.sa_flags = SA_SIGINFO;
  _sa.sa_sigaction = timer_irq_sigalrm_handler;
  sigemptyset(&_sa.sa_mask);
garciay's avatar
garciay committed
245
  if (sigaction(_signal_id, &_sa, NULL) == -1) {
246
247
248
    loggers::get_instance().error("GeoNetworkingLayer::start_beaconing: Sigaction failure: %d", errno);
  }
  // Block timer signal temporarily
garciay's avatar
garciay committed
249
  loggers::get_instance().log("GeoNetworkingLayer::start_beaconing: Blocking signal %d\n", _signal_id);
250
  sigemptyset(&_mask);
garciay's avatar
garciay committed
251
  sigaddset(&_mask, _signal_id);
252
253
254
255
256
  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;
garciay's avatar
garciay committed
257
  _sev.sigev_signo = _signal_id; // Use signal alarm
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
  _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
garciay's avatar
garciay committed
278
  loggers::get_instance().log("GeoNetworkingLayer::start_beaconing: Unblocking signal %d\n", _signal_id);
279
280
281
  if (sigprocmask(SIG_UNBLOCK, &_mask, NULL) == -1) {
    loggers::get_instance().error("GeoNetworkingLayer::start_beaconing: Sigprocmask failure: %d", errno);
  }
garciay's avatar
garciay committed
282
283
284
285
286
287
288
289
290
291
292
293
294
} // End of start_beaconing method

void GeoNetworkingLayer::start_beaconing(const LibItsGeoNetworking__TypesAndValues::GeoNetworkingPdu& p_beacon) {
  loggers::get_instance().log_msg(">>> GeoNetworkingLayer::start_beaconing", p_beacon);

  // Initialize the beacon
  if (_beacon != nullptr) {
    delete _beacon;
  }
  _beacon = new LibItsGeoNetworking__TypesAndValues::GeoNetworkingPdu(p_beacon);

  start_beaconing(); // TODO Refined adding a boolean return code
} // End of start_beaconing method
295
296
297
298
299

void GeoNetworkingLayer::stop_beaconing() {
  loggers::get_instance().log(">>> GeoNetworkingLayer::stop_beaconing");
  
  // Block timer signal temporarily
garciay's avatar
garciay committed
300
  loggers::get_instance().log("GeoNetworkingLayer::stop_beaconing: Blocking signal %d\n", _signal_id);
301
  sigemptyset(&_mask);
garciay's avatar
garciay committed
302
  sigaddset(&_mask, _signal_id);
303
304
305
306
307
  if (sigprocmask(SIG_SETMASK, &_mask, NULL) == -1) {
    loggers::get_instance().error("GeoNetworkingLayer::stop_beaconing: Sigprocmask failure: %d", errno);
  }	
  timer_delete(_timerid);
  _timerid = 0;
garciay's avatar
garciay committed
308
} // End of stop_beaconing method
309

310
311
void GeoNetworkingLayer::send_beacon() {
  loggers::get_instance().log(">>> GeoNetworkingLayer::send_beacon");
312
  
313
  ExtendedHeader* eh = static_cast<ExtendedHeader *>(_beacon->gnPacket().packet().extendedHeader().get_opt_value());
garciay's avatar
garciay committed
314
  if (eh == NULL) {
315
    loggers::get_instance().error("GeoNetworkingLayer::send_beacon: Wrong cast");
garciay's avatar
garciay committed
316
  }
317
  // Update timestamp
garciay's avatar
garciay committed
318
319
320
  unsigned long long ms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count() - 1072911600000L;  // TODO Add method such as its_tme() & its_time_mod()
  eh->beaconHeader().srcPosVector().timestamp__().set_long_long_val(static_cast<unsigned int>(ms));
  //loggers::get_instance().log_msg("GeoNetworkingLayer::send_beacon: ", *_beacon);
321
322
323
324
325
326
327
  // Encode message using TITAN because of payload in omited
  TTCN_Buffer encoding_buffer;
  _beacon->encode(*(_beacon->get_descriptor()), encoding_buffer, TTCN_EncDec::CT_RAW);
  OCTETSTRING data(encoding_buffer.get_len(), encoding_buffer.get_data());
  // Send it
  Params params(_params);
  sendData(data, params);
garciay's avatar
garciay committed
328
  
garciay's avatar
garciay committed
329
  //loggers::get_instance().log("<<< GeoNetworkingLayer::send_beacon");
330
} // End of send_beacon method
garciay's avatar
garciay committed
331

garciay's avatar
garciay committed
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
void GeoNetworkingLayer::start_pass_beaconing(const LibItsGeoNetworking__TypesAndValues::BeaconHeader& p_beacon) {
  loggers::get_instance().log_msg(">>> GeoNetworkingLayer::start_pass_beaconing", p_beacon);

  const LibItsGeoNetworking__TypesAndValues::LongPosVector& lpv = p_beacon.srcPosVector();
  if (!_pass_beacon_table.has_entry(lpv.gnAddr().mid())) {
    _pass_beacon_table.add_entry(lpv);
  } // TODO Refined adding a boolean return code
} // End of start_pass_beaconing method

void GeoNetworkingLayer::stop_pass_beaconing() {
  loggers::get_instance().log(">>> GeoNetworkingLayer::stop_pass_beaconing");

  _pass_beacon_table.reset();
} // End of stop_pass_beaconing method

garciay's avatar
garciay committed
347
348
349
350
351
352
353
354
355
356
357
const LongPosVector* GeoNetworkingLayer::get_lpv(const GN__Address& p_gn_address)
{
  loggers::get_instance().log_msg(">>> GeoNetworkingLayer::get_lpv", p_gn_address);
  
  const LongPosVector* lpv = nullptr;
  if (_location_table.has_entry(p_gn_address.mid())) {
    lpv = _location_table.get_entry(p_gn_address.mid());
  }
  return lpv;
} // End of get_lpv

358
359
360
361
362
void GeoNetworkingLayer::fill_beacon(INTEGER& p_latitude, INTEGER& p_longitude, OCTETSTRING& p_ll_address)
{
  _beacon = new GeoNetworkingPdu();
  HeaderTST h;
  h.beaconHdr() = BeaconHeaderType(
garciay's avatar
garciay committed
363
364
365
                                   HeaderType(HeaderType::e__beacon),
                                   0
                                   );
366
367
  ExtendedHeader eh;
  eh.beaconHeader() = BeaconHeader(
garciay's avatar
garciay committed
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
                                   LongPosVector(
                                                 GN__Address(
                                                             TypeOfAddress(TypeOfAddress::e__manual),
                                                             StationType(StationType::e__roadSideUnit),
                                                             33,
                                                             p_ll_address
                                                             ),
                                                 0,
                                                 p_latitude,
                                                 p_longitude,
                                                 int2bit(0, 1),
                                                 0,
                                                 0
                                                 )
                                   );
383
  _beacon->basicHeader() = BasicHeader(
garciay's avatar
garciay committed
384
385
386
387
388
389
390
391
392
393
394
                                       0,
                                       BasicNextHeader(
                                                       BasicNextHeader::e__commonHeader
                                                       ),
                                       0,
                                       Lifetime(
                                                4,
                                                LtBase(LtBase::e__50ms)
                                                ),
                                       5
                                       );
395
  _beacon->gnPacket().packet() = GnNonSecuredPacket(
garciay's avatar
garciay committed
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
                                                    CommonHeader(
                                                                 NextHeader(
                                                                            NextHeader::e__any
                                                                            ),
                                                                 0,
                                                                 h,
                                                                 TrafficClass(
                                                                              SCF(SCF::e__scfDisabled),
                                                                              ChannelOffload(ChannelOffload::e__choffDisabled),
                                                                              0
                                                                              ),
                                                                 int2bit(0, 8),
                                                                 0,
                                                                 1,
                                                                 0
                                                                 ),
                                                    OPTIONAL<ExtendedHeader>(eh),
                                                    OPTIONAL<GnRawPayload>()
                                                    );
415
416
417
  _beacon->gnPacket().packet().payload().set_to_omit();
  _beacon->gnPacket().securedMsg().set_to_omit();
  //  loggers::get_instance().log_msg("GeoNetworkingLayer::GeoNetworkingLayer: beacon value: ", *p._beacon);
garciay's avatar
garciay committed
418
} // End of fill_beacon method
419
420
  
void GeoNetworkingLayer::timer_irq_sigalrm_handler(int p_signal, siginfo_t *p_signal_info, void *p_uc) {
garciay's avatar
garciay committed
421
  //loggers::get_instance().log(">>> GeoNetworkingLayer::timer_irq_sigalrm_handler: Caught signal %d", p_signal);
422
423
424
425

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

garciay's avatar
garciay committed
426
class GeoNetworkingFactory: public LayerFactory {
garciay's avatar
garciay committed
427
  static GeoNetworkingFactory _f;
garciay's avatar
garciay committed
428
public:
garciay's avatar
garciay committed
429
430
  GeoNetworkingFactory();
  virtual Layer * createLayer(const std::string & type,
garciay's avatar
garciay committed
431
                              const std::string & param);
garciay's avatar
garciay committed
432
433
434
};

GeoNetworkingFactory::GeoNetworkingFactory() {
garciay's avatar
garciay committed
435
436
437
  // Register factory
  loggers::get_instance().log(">>> GeoNetworkingFactory::GeoNetworkingFactory");
  LayerStackBuilder::RegisterLayerFactory("GN", this);
garciay's avatar
garciay committed
438
439
440
}

Layer * GeoNetworkingFactory::createLayer(const std::string & type, const std::string & param) {
garciay's avatar
garciay committed
441
  return new GeoNetworkingLayer(type, param);
garciay's avatar
garciay committed
442
443
444
}

GeoNetworkingFactory GeoNetworkingFactory::_f;