Newer
Older
#include "GeoNetworkingLayer.hh"
#include "GeoNetworkingTypes.hh"
#include "loggers.hh"
GeoNetworkingLayer::GeoNetworkingLayer(const std::string & p_type, const std::string & param) : TLayer<LibItsGeoNetworking__TestSystem::GeoNetworkingPort>(p_type), _params(), _codec(), _beacon(NULL), _thread(NULL), _sendData(), _running(FALSE) {
loggers::get_instance().log(">>> GeoNetworkingLayer::GeoNetworkingLayer: %s, %s", to_string().c_str(), param.c_str());
// 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");
if (it == _params.cend()) {
_params.insert(std::pair<std::string, std::string>(std::string("mac_bc"), "FFFFFFFFFFFF"));
}
fill_beacon(latitude, longitude, ll_address);
it = _params.find("");
if ((it != _params.cend()) && (it->second.compare("1") == 0)) {
start_beaconing();
}
}
void GeoNetworkingLayer::sendMsg(const LibItsGeoNetworking__TestSystem::GeoNetworkingReq& p, Params& params) {
void GeoNetworkingLayer::sendData(OCTETSTRING& data, Params& params) {
loggers::get_instance().log_msg(">>> GeoNetworkingLayer::sendData: ", data);
while (_sendData.try_lock() == FALSE) {
// not ready yet
std::this_thread::sleep_for(std::chrono::milliseconds(1));
} // End of 'while' statement
_sendData.unlock();
loggers::get_instance().log("<<< GeoNetworkingLayer::sendData");
void GeoNetworkingLayer::receiveData(OCTETSTRING& data, Params& params) {
loggers::get_instance().log_msg(">>> GeoNetworkingLayer::receiveData: ", data);
// Decode the payload
LibItsGeoNetworking__TestSystem::GeoNetworkingInd p;
_codec.decode(data, p.msgIn(), ¶ms);
loggers::get_instance().log("GeoNetworkingLayer::receiveData: dst=%s", it->second.c_str());
p.macDestinationAddress() = str2oct(CHARSTRING(it->second.c_str()));
} else {
p.macDestinationAddress() = str2oct(CHARSTRING(_params["mac_bc"].c_str()));
}
// 2. ssp
it = params.find(Params::ssp);
if (it != params.cend()) {
loggers::get_instance().log("GeoNetworkingLayer::receiveData: ssp=%s", it->second.c_str());
p.ssp() = str2bit(CHARSTRING(it->second.c_str()));
} else {
p.ssp().set_to_omit();
// 3. its_aid
it = params.find(Params::its_aid);
if (it != params.cend()) {
loggers::get_instance().log("GeoNetworkingLayer::receiveData: its_aid=%s", it->second.c_str());
p.its__aid() = std::stoi(it->second.c_str());
} else {
p.its__aid().set_to_omit();
}
// 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
loggers::get_instance().log(">>> GeoNetworkingLayer::start_beaconing");
// Sanity checks
if (_thread != NULL) { // Already started
return;
}
// Create the offline reader thread
_thread = new std::thread(&GeoNetworkingLayer::run_beaconing, (void *)this);
if (_thread == NULL) {
loggers::get_instance().error("GeoNetworkingLayer::start_beaconing: Failed to start beaconing thread");
}
// Wait for the thread
while (_running == FALSE) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
// Thread was started
loggers::get_instance().log("<<< PcapLayer::PcapLayer");
}
void GeoNetworkingLayer::stop_beaconing() {
loggers::get_instance().log(">>> GeoNetworkingLayer::stop_beaconing");
if (_thread != NULL) {
_running = FALSE;
// Wait for the working thread to terminate
_thread->join();
loggers::get_instance().log("GeoNetworkingLayer::stop_beaconing: Thread were stops");
_thread = NULL;
}
}
void* GeoNetworkingLayer::run_beaconing(void* p_this) {
loggers::get_instance().log(">>> GeoNetworkingLayer::run_beaconing");
// Pointer the main object
GeoNetworkingLayer& p = *static_cast<GeoNetworkingLayer *>(p_this);
Params params(p._params);
std::chrono::milliseconds expiry(1000); // Default is set to 1 second
Params::const_iterator it = params.find("TsBeaconInterval");
if (it != params.cend()) {
expiry = std::chrono::milliseconds(std::stoul(it->second));
}
ExtendedHeader* eh = static_cast<ExtendedHeader *>(p._beacon->gnPacket().packet().extendedHeader().get_opt_value());
if (eh == NULL) {
loggers::get_instance().error("GeoNetworkingLayer::run_beaconing: Wrong cast");
}
GeoNetworkingCodec codec;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
while (p._running == TRUE) { // Loop while _running flag is up
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()
// Encode message using TITAN because of payload in omited
TTCN_Buffer encoding_buffer;
p._beacon->encode(*(p._beacon->get_descriptor()), encoding_buffer, TTCN_EncDec::CT_RAW);
OCTETSTRING data(encoding_buffer.get_len(), encoding_buffer.get_data());
ms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count() + expiry.count();
while ((p._running == TRUE) && (ms > std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count()));
} // End of 'while' statement<
loggers::get_instance().log("<<< GeoNetworkingLayer::run_beaconing");
return NULL;
}
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
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);
}
class GeoNetworkingFactory: public LayerFactory {
GeoNetworkingFactory();
virtual Layer * createLayer(const std::string & type,
const std::string & param);
};
GeoNetworkingFactory::GeoNetworkingFactory() {
// Register factory
loggers::get_instance().log(">>> GeoNetworkingFactory::GeoNetworkingFactory");
LayerStackBuilder::RegisterLayerFactory("GN", this);
}
Layer * GeoNetworkingFactory::createLayer(const std::string & type, const std::string & param) {
}
GeoNetworkingFactory GeoNetworkingFactory::_f;