GeoNetworkingLayer.cc 7.18 KB
Newer Older
garciay's avatar
garciay committed
1
2
#include <chrono>

garciay's avatar
garciay committed
3
4
5
6
7
#include "GeoNetworkingLayer.hh"
#include "GeoNetworkingTypes.hh"

#include "loggers.hh"

garciay's avatar
garciay committed
8
9
using namespace LibItsGeoNetworking__TypesAndValues;

10
GeoNetworkingLayer::GeoNetworkingLayer(const std::string & p_type, const std::string & param) : TLayer<LibItsGeoNetworking__TestSystem::GeoNetworkingPort>(p_type), _params(), _codec(), _beacon(NULL), _sendData() {
garciay's avatar
garciay committed
11
  loggers::get_instance().log(">>> GeoNetworkingLayer::GeoNetworkingLayer: %s, %s", to_string().c_str(), param.c_str());
garciay's avatar
garciay committed
12
13
  // Setup parameters
  Params::convert(_params, param);
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
  // 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
32
33
34
  if (it == _params.cend()) {
    _params.insert(std::pair<std::string, std::string>(std::string("mac_bc"), "FFFFFFFFFFFF"));
  }
35
  fill_beacon(latitude, longitude, ll_address);
36
} // End of constructor
37

garciay's avatar
garciay committed
38
GeoNetworkingLayer::~GeoNetworkingLayer() {
39
40
41

} // End of destructor

garciay's avatar
garciay committed
42
void GeoNetworkingLayer::sendMsg(const LibItsGeoNetworking__TestSystem::GeoNetworkingReq& p, Params& params) {
garciay's avatar
garciay committed
43
  loggers::get_instance().log(">>> GeoNetworkingLayer::sendMsg");
garciay's avatar
garciay committed
44
45

  // Encode GeoNetworking PDU
garciay's avatar
garciay committed
46
47
  OCTETSTRING data;
  _codec.encode(p.msgOut(), data);
garciay's avatar
garciay committed
48
  sendData(data, params);
garciay's avatar
garciay committed
49
50
}

garciay's avatar
garciay committed
51
void GeoNetworkingLayer::sendData(OCTETSTRING& data, Params& params) {
garciay's avatar
garciay committed
52
  loggers::get_instance().log_msg(">>> GeoNetworkingLayer::sendData: ", data);
53
54
55
56
  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
57
  sendToAllLayers(data, params);
58
59
  _sendData.unlock();
  loggers::get_instance().log("<<< GeoNetworkingLayer::sendData");
garciay's avatar
garciay committed
60
61
}

garciay's avatar
garciay committed
62
void GeoNetworkingLayer::receiveData(OCTETSTRING& data, Params& params) { 
garciay's avatar
garciay committed
63
  loggers::get_instance().log_msg(">>> GeoNetworkingLayer::receiveData: ", data);
garciay's avatar
garciay committed
64
65
  // Decode the payload
  LibItsGeoNetworking__TestSystem::GeoNetworkingInd p;
66
  _codec.decode(data, p.msgIn(), &params);
garciay's avatar
garciay committed
67
  // Add lower layers parameters
garciay's avatar
garciay committed
68
  // 1. Destination MAC address
garciay's avatar
garciay committed
69
  Params::const_iterator it = params.find(Params::mac_dst);
garciay's avatar
garciay committed
70
  if (it != params.cend()) {
71
    loggers::get_instance().log("GeoNetworkingLayer::receiveData: dst=%s", it->second.c_str());
garciay's avatar
garciay committed
72
73
    p.macDestinationAddress() = str2oct(CHARSTRING(it->second.c_str()));
  } else {
garciay's avatar
garciay committed
74
    p.macDestinationAddress() = str2oct(CHARSTRING(_params["mac_bc"].c_str()));
garciay's avatar
garciay committed
75
76
77
78
  }
  // 2. ssp
  it = params.find(Params::ssp);
  if (it != params.cend()) {
79
    loggers::get_instance().log("GeoNetworkingLayer::receiveData: ssp=%s", it->second.c_str());
garciay's avatar
garciay committed
80
81
82
    p.ssp() = str2bit(CHARSTRING(it->second.c_str()));
  } else {
    p.ssp().set_to_omit();
garciay's avatar
garciay committed
83
  }
garciay's avatar
garciay committed
84
85
86
  // 3. its_aid
  it = params.find(Params::its_aid);
  if (it != params.cend()) {
87
    loggers::get_instance().log("GeoNetworkingLayer::receiveData: its_aid=%s", it->second.c_str());
garciay's avatar
garciay committed
88
89
90
91
92
    p.its__aid() = std::stoi(it->second.c_str());
  } else {
    p.its__aid().set_to_omit();
  }
  
93
94
95
96
97
98
99
100
101
102
  // 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
103
  toAllUpperPorts(p, params);
garciay's avatar
garciay committed
104
105
}

106
107
108
void GeoNetworkingLayer::send_beacon() {
  loggers::get_instance().log(">>> GeoNetworkingLayer::send_beacon");
  ExtendedHeader* eh = static_cast<ExtendedHeader *>(_beacon->gnPacket().packet().extendedHeader().get_opt_value());
garciay's avatar
garciay committed
109
  if (eh == NULL) {
110
    loggers::get_instance().error("GeoNetworkingLayer::send_beacon: Wrong cast");
garciay's avatar
garciay committed
111
  }
112
113
114
115
116
117
118
119
120
121
  // Update timestamp
  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__() = ms;
  // 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
122
  
123
124
  loggers::get_instance().log("<<< GeoNetworkingLayer::send_beacon");
} // End of send_beacon method
garciay's avatar
garciay committed
125

126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
void GeoNetworkingLayer::fill_beacon(INTEGER& p_latitude, INTEGER& p_longitude, OCTETSTRING& p_ll_address)
{
  _beacon = new GeoNetworkingPdu();
  HeaderTST h;
  h.beaconHdr() = BeaconHeaderType(
				   HeaderType(HeaderType::e__beacon),
				   0
				   );
  ExtendedHeader eh;
  eh.beaconHeader() = BeaconHeader(
				   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
						 )
				   );
  _beacon->basicHeader() = BasicHeader(
				       0,
				       BasicNextHeader(
						       BasicNextHeader::e__commonHeader
						       ),
				       0,
				       Lifetime(
						4,
						LtBase(LtBase::e__50ms)
						),
				       5
				       );
  _beacon->gnPacket().packet() = GnNonSecuredPacket(
						    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>()
						    );
  _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
188
class GeoNetworkingFactory: public LayerFactory {
garciay's avatar
garciay committed
189
  static GeoNetworkingFactory _f;
garciay's avatar
garciay committed
190
public:
garciay's avatar
garciay committed
191
192
193
  GeoNetworkingFactory();
  virtual Layer * createLayer(const std::string & type,
			      const std::string & param);
garciay's avatar
garciay committed
194
195
196
};

GeoNetworkingFactory::GeoNetworkingFactory() {
garciay's avatar
garciay committed
197
198
199
  // Register factory
  loggers::get_instance().log(">>> GeoNetworkingFactory::GeoNetworkingFactory");
  LayerStackBuilder::RegisterLayerFactory("GN", this);
garciay's avatar
garciay committed
200
201
202
}

Layer * GeoNetworkingFactory::createLayer(const std::string & type, const std::string & param) {
garciay's avatar
garciay committed
203
  return new GeoNetworkingLayer(type, param);
garciay's avatar
garciay committed
204
205
206
}

GeoNetworkingFactory GeoNetworkingFactory::_f;