......@@ -11,5 +11,5 @@
#pragma once
using namespace std; // Required for isnan()
#include "LibItsCam_TypesAndValues.hh"
#include "LibItsCam_TestSystem.hh"
#include "LibItsCam_TypesAndValues.hh"
#include <algorithm>
#include <cctype>
#include <arpa/inet.h>
#include <cctype>
#include "commsignia_layer_factory.hh"
......@@ -8,11 +8,11 @@
#include "converter.hh"
unsigned char commsignia_layer::_g5_fixed_header[10] = { 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x0D };
unsigned char commsignia_layer::_g5_fixed_header[10] = {0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x0D};
commsignia_layer::commsignia_layer(const std::string & p_type, const std::string & param) : layer(p_type), _params(), _mac_src(), _eth_type() {
commsignia_layer::commsignia_layer(const std::string &p_type, const std::string &param) : layer(p_type), _params(), _mac_src(), _eth_type() {
loggers::get_instance().log(">>> commsignia_layer::commsignia_layer: %s, %s", to_string().c_str(), param.c_str());
// Setup parameters
params::convert(_params, param);
params::const_iterator it = _params.find(params::mac_src);
......@@ -20,7 +20,7 @@ commsignia_layer::commsignia_layer(const std::string & p_type, const std::string
_params.insert(std::pair<std::string, std::string>(std::string("mac_src"), "000000000000"));
}
_mac_src = converter::get_instance().hexa_to_bytes(_params[params::mac_src]);
it = _params.find(params::mac_bc);
it = _params.find(params::mac_bc);
if (it == _params.cend()) {
_params.insert(std::pair<std::string, std::string>(std::string("mac_bc"), "FFFFFFFFFFFF"));
}
......@@ -29,7 +29,7 @@ commsignia_layer::commsignia_layer(const std::string & p_type, const std::string
_params.insert(std::pair<std::string, std::string>(std::string("eth_type"), "8947"));
}
_eth_type = converter::get_instance().hexa_to_bytes(_params[params::eth_type]);
it = _params.find(params::interface_id);
it = _params.find(params::interface_id);
if (it == _params.cend()) {
_params.insert(std::pair<std::string, std::string>(std::string("interface_id"), "1")); // The interfce id for filtering & to send on
}
......@@ -52,7 +52,7 @@ commsignia_layer::commsignia_layer(const std::string & p_type, const std::string
//_params.log();
}
void commsignia_layer::send_data(OCTETSTRING& data, params& params) {
void commsignia_layer::send_data(OCTETSTRING &data, params &params) {
loggers::get_instance().log_msg(">>> commsignia_layer::send_data: ", data);
OCTETSTRING buffer = OCTETSTRING(0, nullptr);
......@@ -69,7 +69,7 @@ void commsignia_layer::send_data(OCTETSTRING& data, params& params) {
loggers::get_instance().log_msg("commsignia_layer::send_data: buffer: Interface=", buffer);
buffer += int2oct(std::stoi(_params[std::string("data_rate")]), 2);
loggers::get_instance().log_msg("commsignia_layer::send_data: buffer: data_rate=", buffer);
buffer += int2oct(7, 1); // MAC user priority
buffer += int2oct(7, 1); // MAC user priority
buffer += int2oct(0x80000000 & std::stoi(_params[std::string("power_tx")]), 4); // Negative number
loggers::get_instance().log_msg("commsignia_layer::send_data: buffer: PowerTx=", buffer);
// Destination MAC address
......@@ -102,19 +102,19 @@ void commsignia_layer::send_data(OCTETSTRING& data, params& params) {
loggers::get_instance().log_msg("commsignia_layer::send_data: buffer: Fixed=", buffer);
buffer += int2oct(data.lengthof(), 2); // Data length
loggers::get_instance().log_msg("commsignia_layer::send_data: buffer: Data length=", buffer);
} // else, LTE-V2X, injection buffer = GN+BTP+CAM/DENM only
} // else, LTE-V2X, injection buffer = GN+BTP+CAM/DENM only
buffer += data; // Payload
loggers::get_instance().log_msg("commsignia_layer::send_data: Final buffer=", buffer);
send_to_all_layers(buffer, params);
}
void commsignia_layer::receive_data(OCTETSTRING& data, params& params) {
void commsignia_layer::receive_data(OCTETSTRING &data, params &params) {
loggers::get_instance().log_msg(">>> commsignia_layer::receive_data: ", data);
const unsigned char* p = static_cast<const unsigned char *>(data);
const unsigned char c2p_ver = (unsigned char)*p;
const unsigned char *p = static_cast<const unsigned char *>(data);
const unsigned char c2p_ver = (unsigned char)*p;
// Check the frame version
if ((c2p_ver != 0x11) && (c2p_ver != 0x17)) { // Rx G5 or LTE-V2X
// Discard it, only use G5 or LTE-V2X RX version
......@@ -125,10 +125,12 @@ void commsignia_layer::receive_data(OCTETSTRING& data, params& params) {
commsignia_layer::c2p_s_v1_rx_t r;
r.s_header.u8_ver_type = (unsigned char)*p++;
loggers::get_instance().log("commsignia_layer::receive_data: version=%02x", r.s_header.u8_ver_type);
memcpy((void*)&r.s_header.u32_tst_sec, (unsigned int*)p, sizeof(unsigned int)); p += sizeof(unsigned int);
loggers::get_instance().log("commsignia_layer::receive_data: time (in s)=%08x", /*ntohl(*/r.s_header.u32_tst_sec)/*)*/;
memcpy((void*)&r.s_header.u32_tst_msec, (unsigned int*)p, sizeof(unsigned int)); p += sizeof(unsigned int);
loggers::get_instance().log("commsignia_layer::receive_data: time (in ms)=%08x", /*ntohl(*/r.s_header.u32_tst_msec)/*)*/;
memcpy((void *)&r.s_header.u32_tst_sec, (unsigned int *)p, sizeof(unsigned int));
p += sizeof(unsigned int);
loggers::get_instance().log("commsignia_layer::receive_data: time (in s)=%08x", /*ntohl(*/ r.s_header.u32_tst_sec) /*)*/;
memcpy((void *)&r.s_header.u32_tst_msec, (unsigned int *)p, sizeof(unsigned int));
p += sizeof(unsigned int);
loggers::get_instance().log("commsignia_layer::receive_data: time (in ms)=%08x", /*ntohl(*/ r.s_header.u32_tst_msec) /*)*/;
r.u8_primary_channel = (unsigned char)*p++;
loggers::get_instance().log("commsignia_layer::receive_data: primary_channel=%02x", r.u8_primary_channel);
r.u8_secondary_channel = (unsigned char)*p++;
......@@ -139,13 +141,17 @@ void commsignia_layer::receive_data(OCTETSTRING& data, params& params) {
loggers::get_instance().log("commsignia_layer::receive_data: data_rate=%02x", r.u8_data_rate);
r.u8_antenna = (unsigned char)*p++;
loggers::get_instance().log("commsignia_layer::receive_data: antenna=%02x", r.u8_antenna);
memcpy((void*)&r.s32_latitude, (int*)p, sizeof(int)); p += sizeof(int);
memcpy((void *)&r.s32_latitude, (int *)p, sizeof(int));
p += sizeof(int);
loggers::get_instance().log("commsignia_layer::receive_data: latitude=%08x", r.s32_latitude);
memcpy((void*)&r.s32_longitude, (int*)p, sizeof(int)); p += sizeof(int);
memcpy((void *)&r.s32_longitude, (int *)p, sizeof(int));
p += sizeof(int);
loggers::get_instance().log("commsignia_layer::receive_data: longitude=%08x", r.s32_longitude);
memcpy((void*)&r.u16_speed, (unsigned short*)p, sizeof(unsigned short)); p += sizeof(unsigned short);
memcpy((void *)&r.u16_speed, (unsigned short *)p, sizeof(unsigned short));
p += sizeof(unsigned short);
loggers::get_instance().log("commsignia_layer::receive_data: speed=%02x", r.u16_speed); // ntohs
memcpy((void*)&r.u16_heading, (unsigned short*)p, sizeof(unsigned short)); p += sizeof(unsigned short);
memcpy((void *)&r.u16_heading, (unsigned short *)p, sizeof(unsigned short));
p += sizeof(unsigned short);
loggers::get_instance().log("commsignia_layer::receive_data: heading=%02x", r.u16_heading);
r.s8_rssi_ant_1 = (unsigned char)*p++;
loggers::get_instance().log("commsignia_layer::receive_data: s8_rssi_ant_1=%02x", r.s8_rssi_ant_1);
......@@ -155,91 +161,105 @@ void commsignia_layer::receive_data(OCTETSTRING& data, params& params) {
loggers::get_instance().log("commsignia_layer::receive_data: s8_noise_ant_1=%02x", r.s8_noise_ant_1);
r.s8_noise_ant_2 = (unsigned char)*p++;
loggers::get_instance().log("commsignia_layer::receive_data: s8_noise_ant_2=%02x", r.s8_noise_ant_2);
memcpy((void*)&r.u16_cbr_ant_1, (unsigned short*)p, sizeof(unsigned short)); p += sizeof(unsigned short);
memcpy((void *)&r.u16_cbr_ant_1, (unsigned short *)p, sizeof(unsigned short));
p += sizeof(unsigned short);
loggers::get_instance().log("commsignia_layer::receive_data: cbr_ant_1=%04x", r.u16_cbr_ant_1);
memcpy((void*)&r.u16_cbr_ant_2, (unsigned short*)p, sizeof(unsigned short)); p += sizeof(unsigned short);
memcpy((void *)&r.u16_cbr_ant_2, (unsigned short *)p, sizeof(unsigned short));
p += sizeof(unsigned short);
loggers::get_instance().log("commsignia_layer::receive_data: cbr_ant_2=%04x", r.u16_cbr_ant_2);
// Filtering on antenna index
loggers::get_instance().log("commsignia_layer::receive_data: compare %02x with %02x", r.u8_antenna, static_cast<unsigned char>(std::stoi(_params[params::interface_id])));
loggers::get_instance().log("commsignia_layer::receive_data: compare %02x with %02x", r.u8_antenna,
static_cast<unsigned char>(std::stoi(_params[params::interface_id])));
if (r.u8_antenna != std::stoi(_params[params::interface_id])) {
// Discard packet
loggers::get_instance().warning("commsignia_layer::receive_data: Discard packet due to wrong antenna id");
// TODO return;
} // else, continue
} // else, continue
} else { // LTE-CV2X
commsignia_layer::c2p_s_v1_rx_cv2x_t r;
r.s_header.u8_ver_type = (unsigned char)*p++;
loggers::get_instance().log("commsignia_layer::receive_data: version=%02x", r.s_header.u8_ver_type);
memcpy((void*)&r.s_header.u32_tst_sec, (unsigned int*)p, sizeof(unsigned int)); p += sizeof(unsigned int);
loggers::get_instance().log("commsignia_layer::receive_data: time (in s)=%08x", /*ntohl(*/r.s_header.u32_tst_sec)/*)*/;
memcpy((void*)&r.s_header.u32_tst_msec, (unsigned int*)p, sizeof(unsigned int)); p += sizeof(unsigned int);
loggers::get_instance().log("commsignia_layer::receive_data: time (in ms)=%08x", /*ntohl(*/r.s_header.u32_tst_msec)/*)*/;
memcpy((void *)&r.s_header.u32_tst_sec, (unsigned int *)p, sizeof(unsigned int));
p += sizeof(unsigned int);
loggers::get_instance().log("commsignia_layer::receive_data: time (in s)=%08x", /*ntohl(*/ r.s_header.u32_tst_sec) /*)*/;
memcpy((void *)&r.s_header.u32_tst_msec, (unsigned int *)p, sizeof(unsigned int));
p += sizeof(unsigned int);
loggers::get_instance().log("commsignia_layer::receive_data: time (in ms)=%08x", /*ntohl(*/ r.s_header.u32_tst_msec) /*)*/;
r.u8_socket_index = (unsigned char)*p++;
loggers::get_instance().log("commsignia_layer::receive_data: u8_socket_index=%02x", r.u8_socket_index);
memcpy((void*)&r.u16_ethertype, (unsigned short*)p, sizeof(unsigned short)); p += sizeof(unsigned short);
memcpy((void *)&r.u16_ethertype, (unsigned short *)p, sizeof(unsigned short));
p += sizeof(unsigned short);
loggers::get_instance().log("commsignia_layer::receive_data: u16_ethertype=%04x", r.u16_ethertype);
r.s8_rssi = (signed char)*p++;
loggers::get_instance().log("commsignia_layer::receive_data: s8_rssi=%02x", r.s8_rssi);
r.u8_datarate_500kbps = (unsigned char)*p++;
loggers::get_instance().log("commsignia_layer::receive_data: u8_datarate_500kbps=%02x", r.u8_datarate_500kbps);
}
commsignia_layer::c2p_802_11p_hdr h;
memcpy((void*)&h.frame_ctrl, (unsigned short*)p, sizeof(unsigned short)); p += sizeof(unsigned short);
memcpy((void *)&h.frame_ctrl, (unsigned short *)p, sizeof(unsigned short));
p += sizeof(unsigned short);
loggers::get_instance().log("commsignia_layer::receive_data: frame_ctrl=%04x", h.frame_ctrl);
memcpy((void*)&h.duration, (unsigned short*)p, sizeof(unsigned short)); p += sizeof(unsigned short);
memcpy((void *)&h.duration, (unsigned short *)p, sizeof(unsigned short));
p += sizeof(unsigned short);
loggers::get_instance().log("commsignia_layer::receive_data: duration=%04x", h.duration);
memcpy((void*)&h.dst_addr, (unsigned short*)p, 6 * sizeof(unsigned char)); p += 6 * sizeof(unsigned char);
memcpy((void*)&h.src_addr, (unsigned short*)p, 6 * sizeof(unsigned char)); p += 6 * sizeof(unsigned char);
memcpy((void*)&h.bss_id, (unsigned short*)p, 6 * sizeof(unsigned char)); p += 6 * sizeof(unsigned char);
memcpy((void*)&h.fragment_seq_num, (unsigned short*)p, sizeof(unsigned short)); p += sizeof(unsigned short);
memcpy((void *)&h.dst_addr, (unsigned short *)p, 6 * sizeof(unsigned char));
p += 6 * sizeof(unsigned char);
memcpy((void *)&h.src_addr, (unsigned short *)p, 6 * sizeof(unsigned char));
p += 6 * sizeof(unsigned char);
memcpy((void *)&h.bss_id, (unsigned short *)p, 6 * sizeof(unsigned char));
p += 6 * sizeof(unsigned char);
memcpy((void *)&h.fragment_seq_num, (unsigned short *)p, sizeof(unsigned short));
p += sizeof(unsigned short);
loggers::get_instance().log("commsignia_layer::receive_data: fragment_seq_num=%04x", h.fragment_seq_num);
OCTETSTRING bid = OCTETSTRING(6, (const unsigned char*)&h.bss_id); // TODO To be removed
OCTETSTRING bid = OCTETSTRING(6, (const unsigned char *)&h.bss_id); // TODO To be removed
loggers::get_instance().log_msg("commsignia_layer::receive_data: bss_id: ", bid);
OCTETSTRING dst = OCTETSTRING(6, (const unsigned char*)&h.dst_addr);
OCTETSTRING dst = OCTETSTRING(6, (const unsigned char *)&h.dst_addr);
loggers::get_instance().log_msg("commsignia_layer::receive_data: dst: ", dst);
OCTETSTRING src = OCTETSTRING(6, (const unsigned char*)&h.src_addr);
OCTETSTRING src = OCTETSTRING(6, (const unsigned char *)&h.src_addr);
loggers::get_instance().log_msg("commsignia_layer::receive_data: src: ", src);
// Filtering on source MAC address of the packet
if (!std::equal(_mac_src.cbegin(), _mac_src.cend(), static_cast<const unsigned char*>(src))) {
if (!std::equal(_mac_src.cbegin(), _mac_src.cend(), static_cast<const unsigned char *>(src))) {
// Discard packet
loggers::get_instance().warning("commsignia_layer::receive_data: Discard packet due to wrong comparison");
//TODO return;
// TODO return;
} // else, continue
int length;
if (c2p_ver == 0x11) {
const commsignia_layer::c2p_llc_hdr* l;
const commsignia_layer::c2p_llc_hdr *l;
if ((ntohs(h.frame_ctrl) & 0xf000) == 0x8000) {
l = (const commsignia_layer::c2p_llc_hdr*)(static_cast<const unsigned char *>(data) + sizeof(commsignia_layer::c2p_s_v1_rx_t) + sizeof(commsignia_layer::c2p_802_11p_hdr) + sizeof(commsignia_layer::c2p_qos_ctrl));
length = sizeof(commsignia_layer::c2p_s_v1_rx_t) + sizeof(commsignia_layer::c2p_802_11p_hdr) + sizeof(commsignia_layer::c2p_qos_ctrl) + sizeof(commsignia_layer::c2p_llc_hdr);
l = (const commsignia_layer::c2p_llc_hdr *)(static_cast<const unsigned char *>(data) + sizeof(commsignia_layer::c2p_s_v1_rx_t) +
sizeof(commsignia_layer::c2p_802_11p_hdr) + sizeof(commsignia_layer::c2p_qos_ctrl));
length = sizeof(commsignia_layer::c2p_s_v1_rx_t) + sizeof(commsignia_layer::c2p_802_11p_hdr) + sizeof(commsignia_layer::c2p_qos_ctrl) +
sizeof(commsignia_layer::c2p_llc_hdr);
} else {
l = (const commsignia_layer::c2p_llc_hdr*)(p + sizeof(commsignia_layer::c2p_s_v1_rx_t) + sizeof(commsignia_layer::c2p_802_11p_hdr));
l = (const commsignia_layer::c2p_llc_hdr *)(p + sizeof(commsignia_layer::c2p_s_v1_rx_t) + sizeof(commsignia_layer::c2p_802_11p_hdr));
length = sizeof(commsignia_layer::c2p_s_v1_rx_t) + sizeof(commsignia_layer::c2p_802_11p_hdr) + sizeof(commsignia_layer::c2p_llc_hdr);
}
} else { // LTE-V2X
length = sizeof(commsignia_layer::c2p_s_v1_rx_cv2x_t) + sizeof(commsignia_layer::c2p_802_11p_hdr) + 10/*Fixed size*/;
length = sizeof(commsignia_layer::c2p_s_v1_rx_cv2x_t) + sizeof(commsignia_layer::c2p_802_11p_hdr) + 10 /*Fixed size*/;
}
// Check ether type
//if ((_eth_type[1] == (unsigned char)((l->type & 0xff00) >> 8)) && (_eth_type[0] == (unsigned char)(l->type & 0xff))) { // Warning: Network ordered bytes
// Extract payload
data = OCTETSTRING(data.lengthof() - length, length + static_cast<const unsigned char *>(data));
//loggers::get_instance().log_msg("commsignia_layer::receive_data: payload for upper layer:", data);
// Update params
CHARSTRING s = oct2str(dst);
params[params::mac_dst] = std::string(static_cast<const char *>(s));
s = oct2str(src);
params[params::mac_src] = std::string(static_cast<const char *>(s));
receive_to_all_layers(data, params);
/*} else {
// Discard packet
loggers::get_instance().warning("commsignia_layer::receive_data: Discard packet due to wrong ethernet type");
//TODO return;
}*/
// if ((_eth_type[1] == (unsigned char)((l->type & 0xff00) >> 8)) && (_eth_type[0] == (unsigned char)(l->type & 0xff))) { // Warning: Network ordered bytes
// Extract payload
data = OCTETSTRING(data.lengthof() - length, length + static_cast<const unsigned char *>(data));
// loggers::get_instance().log_msg("commsignia_layer::receive_data: payload for upper layer:", data);
// Update params
CHARSTRING s = oct2str(dst);
params[params::mac_dst] = std::string(static_cast<const char *>(s));
s = oct2str(src);
params[params::mac_src] = std::string(static_cast<const char *>(s));
receive_to_all_layers(data, params);
/*} else {
// Discard packet
loggers::get_instance().warning("commsignia_layer::receive_data: Discard packet due to wrong ethernet type");
//TODO return;
}*/
}
commsignia_layer_factory commsignia_layer_factory::_f;
......@@ -10,8 +10,8 @@
*/
#pragma once
#include "t_layer.hh"
#include "params.hh"
#include "t_layer.hh"
class OCTETSTRING; //! Forward declaration of TITAN class
......@@ -20,67 +20,67 @@ class OCTETSTRING; //! Forward declaration of TITAN class
* \brief This class provides description of ITS Commsignia port protocol layer
*/
class commsignia_layer : public layer {
static constexpr unsigned char LL_ADDR_LENGTH = 6;
static constexpr unsigned char LL_ADDR_LENGTH = 6;
static constexpr unsigned char LL_ORG_CODE_LENGTH = 3;
/**
* \struct C2P packet description
*/
typedef struct {
unsigned char u8_ver_type;
unsigned int u32_tst_sec;
unsigned int u32_tst_msec;
unsigned int u32_tst_sec;
unsigned int u32_tst_msec;
} __attribute__((__packed__)) c2p_s_header_t;
typedef struct {
c2p_s_header_t s_header;
unsigned char u8_primary_channel;
unsigned char u8_secondary_channel;
unsigned char u8_used_interface;
unsigned char u8_data_rate;
unsigned char u8_antenna;
int s32_latitude;
int s32_longitude;
unsigned char u8_primary_channel;
unsigned char u8_secondary_channel;
unsigned char u8_used_interface;
unsigned char u8_data_rate;
unsigned char u8_antenna;
int s32_latitude;
int s32_longitude;
unsigned short u16_speed;
unsigned short u16_heading;
signed char s8_rssi_ant_1;
signed char s8_rssi_ant_2;
signed char s8_noise_ant_1;
signed char s8_noise_ant_2;
signed char s8_rssi_ant_1;
signed char s8_rssi_ant_2;
signed char s8_noise_ant_1;
signed char s8_noise_ant_2;
unsigned short u16_cbr_ant_1;
unsigned short u16_cbr_ant_2;
} __attribute__((__packed__)) c2p_s_v1_rx_t;
typedef struct {
c2p_s_header_t s_header;
unsigned char u8_primary_channel;
unsigned char u8_secondary_channel;
unsigned char u8_used_interface;
unsigned char u8_data_rate;
unsigned char u8_antenna;
int s32_latitude;
int s32_longitude;
unsigned char u8_primary_channel;
unsigned char u8_secondary_channel;
unsigned char u8_used_interface;
unsigned char u8_data_rate;
unsigned char u8_antenna;
int s32_latitude;
int s32_longitude;
unsigned short u16_speed;
unsigned short u16_heading;
signed char s8_txp;
signed char s8_rssi_ant_1;
signed char s8_rssi_ant_2;
signed char s8_txp;
signed char s8_rssi_ant_1;
signed char s8_rssi_ant_2;
} __attribute__((__packed__)) c2p_s_v1_tx_t;
typedef struct {
c2p_s_header_t s_header;
unsigned char u8_socket_index;
unsigned char u8_socket_index;
unsigned short u16_ethertype;
signed char s8_rssi;
unsigned char u8_datarate_500kbps;
signed char s8_rssi;
unsigned char u8_datarate_500kbps;
} __attribute__((__packed__)) c2p_s_v1_rx_cv2x_t;
typedef struct {
c2p_s_header_t s_header;
unsigned char u8_b_sps;
unsigned char u8_b_sps;
unsigned short u16_sps_port;
unsigned short u16_event_port;
int s32_tx_pwr_dbm;
int s32_bw_res_v2xid;
int s32_bw_res_period_interval_ms;
int s32_bw_res_tx_reservation_size_bytes;
unsigned char u8_bw_res_tx_priority;
int s32_tx_pwr_dbm;
int s32_bw_res_v2xid;
int s32_bw_res_period_interval_ms;
int s32_bw_res_tx_reservation_size_bytes;
unsigned char u8_bw_res_tx_priority;
} __attribute__((__packed__)) c2p_s_v1_tx_cv2x_t;
/**
......@@ -89,48 +89,48 @@ class commsignia_layer : public layer {
typedef struct {
unsigned short frame_ctrl;
unsigned short duration;
unsigned char dst_addr[commsignia_layer::LL_ADDR_LENGTH];
unsigned char src_addr[commsignia_layer::LL_ADDR_LENGTH];
unsigned char bss_id[commsignia_layer::LL_ADDR_LENGTH];
unsigned char dst_addr[commsignia_layer::LL_ADDR_LENGTH];
unsigned char src_addr[commsignia_layer::LL_ADDR_LENGTH];
unsigned char bss_id[commsignia_layer::LL_ADDR_LENGTH];
unsigned short fragment_seq_num;
} __attribute__((__packed__)) c2p_802_11p_hdr;
typedef unsigned short c2p_qos_ctrl;
/**
* \struct C2P/c2p_s_llc_hdr_t
*/
typedef struct {
unsigned char dsap;
unsigned char ssap;
unsigned char ctrl;
unsigned char org_code[commsignia_layer::LL_ORG_CODE_LENGTH];
unsigned char dsap;
unsigned char ssap;
unsigned char ctrl;
unsigned char org_code[commsignia_layer::LL_ORG_CODE_LENGTH];
unsigned short type;
} __attribute__((__packed__)) c2p_llc_hdr;
params _params; //! Layer parameters
params _params; //! Layer parameters
std::vector<unsigned char> _mac_src; //! Used to optimize filtering on source mac address in \see commsignia_layer::receive_data method
std::vector<unsigned char> _eth_type; //! Used to optimize filtering on ethernet type in \see commsignia_layer::receive_data method
//! Fixed header for packet injection
static unsigned char _g5_fixed_header[10];
static unsigned char _cv2x_fixed_header[10];
public:
//! \publicsection
/*!
* \brief Specialised constructor
* Create a new instance of the commsignia_layer class
* \param[in] p_type \todo
* \param[in] p_param \todo
*/
commsignia_layer(const std::string & p_type, const std::string & param);
/*!
* \brief Specialised constructor
* Create a new instance of the commsignia_layer class
* \param[in] p_type \todo
* \param[in] p_param \todo
*/
commsignia_layer(const std::string &p_type, const std::string &param);
/*!
* \brief Default destructor
* \remark If \see _reconnect_on_send is set to false, the disconnection is done by the destructor
*/
virtual ~commsignia_layer() {};
virtual ~commsignia_layer(){};
virtual void send_data(OCTETSTRING& data, params& params);
virtual void receive_data(OCTETSTRING& data, params& info);
virtual void send_data(OCTETSTRING &data, params &params);
virtual void receive_data(OCTETSTRING &data, params &info);
}; // End of class commsignia_layer
......@@ -18,9 +18,9 @@
* \class commsignia_layer_factory
* \brief This class provides a factory class to create an commsignia_layer class instance
*/
class commsignia_layer_factory: public layer_factory {
class commsignia_layer_factory : public layer_factory {
static commsignia_layer_factory _f; //! Reference to the unique instance of this class
public: //! \publicsection
public: //! \publicsection
/*!
* \brief Default constructor
* Create a new instance of the udp_layer_factory class
......@@ -38,8 +38,5 @@ public: //! \publicsection
* \return 0 on success, -1 otherwise
* \inline
*/
inline virtual layer* create_layer(const std::string& p_type, const std::string& p_param) {
return new commsignia_layer(p_type, p_param);
};
inline virtual layer *create_layer(const std::string &p_type, const std::string &p_param) { return new commsignia_layer(p_type, p_param); };
}; // End of class commsignia_layer_factory
#include "LibItsDenm_TestSystem.hh"
#include "denm_codec.hh"
#include "LibItsDenm_TestSystem.hh"
#include "asn1/asn_application.h" // from asn1c
#include "loggers.hh"
int denm_codec::encode (const DENM__PDU__Descriptions::DENM& p_denm, OCTETSTRING& p_data)
{
int denm_codec::encode(const DENM__PDU__Descriptions::DENM &p_denm, OCTETSTRING &p_data) {
loggers::get_instance().log_msg(">>> denm_codec::encode: ", p_denm);
BITSTRING b;
int rc = asn_codec.encode(p_denm, b);
if(rc){
int rc = asn_codec.encode(p_denm, b);
if (rc) {
p_data = bit2oct(b);
}
loggers::get_instance().log("<<< denm_codec::encode: %d", rc);
return rc;
}
int denm_codec::decode (const OCTETSTRING& p_data, DENM__PDU__Descriptions::DENM& p_denm, params* params)
{
int denm_codec::decode(const OCTETSTRING &p_data, DENM__PDU__Descriptions::DENM &p_denm, params *params) {
loggers::get_instance().log_msg(">>> denm_codec::decode:", p_data);
int rc = asn_codec.decode(oct2bit(p_data), p_denm);
loggers::get_instance().log("denm_codec::decode: ASN.1 codec returned %d", rc);
if(rc) {
if (rc) {
loggers::get_instance().log_msg("denm_codec::decode: ", p_denm);
}
return rc;
......
......@@ -14,14 +14,13 @@ namespace DENM__PDU__Descriptions {
class DENM;
}
class denm_codec : public codec<DENM__PDU__Descriptions::DENM, DENM__PDU__Descriptions::DENM>
{
class denm_codec : public codec<DENM__PDU__Descriptions::DENM, DENM__PDU__Descriptions::DENM> {
denm_pdu_codec asn_codec;
public:
explicit denm_codec() : codec<DENM__PDU__Descriptions::DENM, DENM__PDU__Descriptions::DENM>(), asn_codec() { };
virtual ~denm_codec() { };
explicit denm_codec() : codec<DENM__PDU__Descriptions::DENM, DENM__PDU__Descriptions::DENM>(), asn_codec(){};
virtual ~denm_codec(){};
virtual int encode (const DENM__PDU__Descriptions::DENM& denm, OCTETSTRING& data);
virtual int decode (const OCTETSTRING& data, DENM__PDU__Descriptions::DENM&, params* params = NULL);
virtual int encode(const DENM__PDU__Descriptions::DENM &denm, OCTETSTRING &data);
virtual int decode(const OCTETSTRING &data, DENM__PDU__Descriptions::DENM &, params *params = NULL);
};
......@@ -6,11 +6,11 @@
#include "loggers.hh"
denm_layer::denm_layer(const std::string & p_type, const std::string & param) : t_layer<LibItsDenm__TestSystem::DenmPort>(p_type), _params(), _codec() {
denm_layer::denm_layer(const std::string &p_type, const std::string &param) : t_layer<LibItsDenm__TestSystem::DenmPort>(p_type), _params(), _codec() {
loggers::get_instance().log(">>> denm_layer::denm_layer: %s, %s", to_string().c_str(), param.c_str());
// Setup parameters
params::convert(_params, param);
_params.insert(std::make_pair<std::string, std::string>("its_aid", "37")); // ETSI TS 102 965 V1.2.1 (2015-06)
_params.insert(std::make_pair<std::string, std::string>("its_aid", "37")); // ETSI TS 102 965 V1.2.1 (2015-06)
_params.insert(std::make_pair<std::string, std::string>("payload_type", "1")); // DE message id - See ETSI TS 102 894
// Register this object for AdapterControlPort
......@@ -18,7 +18,7 @@ denm_layer::denm_layer(const std::string & p_type, const std::string & param) :
registration<denm_layer>::get_instance().add_item(p_type, this);
}
void denm_layer::sendMsg(const LibItsDenm__TestSystem::DenmReq& p, params& params){
void denm_layer::sendMsg(const LibItsDenm__TestSystem::DenmReq &p, params &params) {
loggers::get_instance().log_msg(">>> denm_layer::sendMsg: ", p);
// Encode DENM PDU
......@@ -27,27 +27,26 @@ void denm_layer::sendMsg(const LibItsDenm__TestSystem::DenmReq& p, params& param
loggers::get_instance().warning("denm_layer::sendMsg: Encoding failure");
return;
}
send_data(data, _params);
}
void denm_layer::send_data(OCTETSTRING& data, params& params) {
void denm_layer::send_data(OCTETSTRING &data, params &params) {
loggers::get_instance().log_msg(">>> denm_layer::send_data: ", data);
//params.log();
// params.log();
send_to_all_layers(data, params);
}
void denm_layer::receive_data(OCTETSTRING& data, params& params)
{
void denm_layer::receive_data(OCTETSTRING &data, params &params) {
loggers::get_instance().log_msg(">>> denm_layer::receive_data: ", data);
// Sanity check
if (*(static_cast<const unsigned char*>(data)+ 1) != 0x01) { // Check that received packet has DEN message id - See ETSI TS 102 894
if (*(static_cast<const unsigned char *>(data) + 1) != 0x01) { // Check that received packet has DEN message id - See ETSI TS 102 894
// Not a DENM message, discard it
loggers::get_instance().warning("denm_layer::receive_data: Wrong message id: 0x%02x", *(static_cast<const unsigned char*>(data)+ 1));
loggers::get_instance().warning("denm_layer::receive_data: Wrong message id: 0x%02x", *(static_cast<const unsigned char *>(data) + 1));
return;
}
// Decode the payload
LibItsDenm__TestSystem::DenmInd p;
_codec.decode(data, p.msgIn());
......@@ -55,7 +54,7 @@ void denm_layer::receive_data(OCTETSTRING& data, params& params)
// Discard it
return;
} // else, continue
// Process lower layer data
// recvTime
params::const_iterator it = params.find(params::timestamp);
......@@ -128,12 +127,12 @@ void denm_layer::receive_data(OCTETSTRING& data, params& params)
} else {
p.its__aid().set_to_omit();
}
// Pass it to the ports if any
to_all_upper_ports(p, params);
}
int denm_layer::enable_secured_mode(const std::string& p_certificate_id, const boolean p_enforce_security) {
int denm_layer::enable_secured_mode(const std::string &p_certificate_id, const boolean p_enforce_security) {
loggers::get_instance().log(">>> denm_layer::enable_secured_mode: '%s' - %x", p_certificate_id.c_str(), p_enforce_security);
return 0;
......
......@@ -10,39 +10,39 @@
*/
#pragma once
#include "t_layer.hh"
#include "denm_codec.hh"
#include "t_layer.hh"
namespace LibItsDenm__TestSystem {
class DenmPort; //! Forward declaration of TITAN class
class DenmReq; //! Forward declaration of TITAN class
class DenmInd; //! Forward declaration of TITAN class
}
} // namespace LibItsDenm__TestSystem
/*!
* \class denm_layer
* \brief This class provides description of ITS DENM protocol layer
*/
class denm_layer : public t_layer<LibItsDenm__TestSystem::DenmPort> {
params _params; //! Layer parameters
denm_codec _codec; //! DENM codec
public: //! \publicsection
params _params; //! Layer parameters
denm_codec _codec; //! DENM codec
public: //! \publicsection
/*!
* \brief Default constructor
* Create a new instance of the denm_layer class
*/
explicit denm_layer() : t_layer<LibItsDenm__TestSystem::DenmPort>(), _params(), _codec() {};
explicit denm_layer() : t_layer<LibItsDenm__TestSystem::DenmPort>(), _params(), _codec(){};
/*!
* \brief Specialised constructor
* Create a new instance of the denm_layer class
* \param[in] p_type \todo
* \param[in] p_param \todo
*/
denm_layer(const std::string& p_type, const std::string& param);
denm_layer(const std::string &p_type, const std::string &param);
/*!
* \brief Default destructor
*/
virtual ~denm_layer() {};
virtual ~denm_layer(){};
/*!
* \fn void sendMsg(const LibItsDenm__TestSystem::DenmReq& p_denm_req, params& p_params);
......@@ -50,8 +50,8 @@ public: //! \publicsection
* \param[in] p_denm_req The DEN message to be sent
* \param[in] p_params Some parameters to overwrite default value of the lower layers parameters
*/
void sendMsg(const LibItsDenm__TestSystem::DenmReq& p_denm_req, params& params);
void sendMsg(const LibItsDenm__TestSystem::DenmReq &p_denm_req, params &params);
/*!
* \virtual
* \fn void send_data(OCTETSTRING& data, params& params);
......@@ -59,7 +59,7 @@ public: //! \publicsection
* \param[in] p_data The data to be sent
* \param[in] p_params Some parameters to overwrite default value of the lower layers parameters
*/
virtual void send_data(OCTETSTRING& data, params& params);
virtual void send_data(OCTETSTRING &data, params &params);
/*!
* \virtual
* \fn void receive_data(OCTETSTRING& data, params& params);
......@@ -67,11 +67,10 @@ public: //! \publicsection
* \param[in] p_data The bytes formated data received
* \param[in] p_params Some lower layers parameters values when data was received
*/
virtual void receive_data(OCTETSTRING& data, params& info);
virtual void receive_data(OCTETSTRING &data, params &info);
int enable_secured_mode(const std::string& p_certificate_id, const boolean p_enforce_security);
int enable_secured_mode(const std::string &p_certificate_id, const boolean p_enforce_security);
int disable_secured_mode();
}; // End of class denm_layer
......@@ -20,7 +20,7 @@
*/
class denm_layer_factory : public layer_factory {
static denm_layer_factory _f; //! Reference to the unique instance of this class
public: //! \publicsection
public: //! \publicsection
/*!
* \brief Default constructor
* Create a new instance of the denm_layer_factory class
......@@ -38,7 +38,5 @@ public: //! \publicsection
* \return 0 on success, -1 otherwise
* \inline
*/
inline virtual layer* create_layer(const std::string& p_type, const std::string& p_param){
return new denm_layer(p_type, p_param);
};
inline virtual layer *create_layer(const std::string &p_type, const std::string &p_param) { return new denm_layer(p_type, p_param); };
}; // End of class denm_layer_factory
#include "LibItsDenm_TestSystem.hh"
#include "denm_pdu_codec.hh"
#include "LibItsDenm_TestSystem.hh"
#include "asn1/asn_application.h" // from asn1c
#include "loggers.hh"
extern "C" {
extern asn_TYPE_descriptor_t asn_DEF_DENM;
extern asn_TYPE_descriptor_t asn_DEF_DENM;
}
int denm_pdu_codec::encode (const DENM__PDU__Descriptions::DENM& p_denm, BITSTRING& p_data)
{
int denm_pdu_codec::encode(const DENM__PDU__Descriptions::DENM &p_denm, BITSTRING &p_data) {
return _encode(DENM__PDU__Descriptions::DENM_descr_, asn_DEF_DENM, p_denm, p_data);
}
int denm_pdu_codec::decode (const BITSTRING& p_data, DENM__PDU__Descriptions::DENM& p_denm)
{
int denm_pdu_codec::decode(const BITSTRING &p_data, DENM__PDU__Descriptions::DENM &p_denm) {
return _decode(DENM__PDU__Descriptions::DENM_descr_, asn_DEF_DENM, p_data, p_denm);
}
#pragma once
#include "codec.hh"
#include "per_codec.hh"
#include "params.hh"
#include "per_codec.hh"
class BITSTRING;
class OCTETSTRING;
......@@ -14,10 +14,9 @@ namespace DENM__PDU__Descriptions {
class DENM;
}
class denm_pdu_codec : public per_codec <DENM__PDU__Descriptions::DENM>
{
class denm_pdu_codec : public per_codec<DENM__PDU__Descriptions::DENM> {
public:
explicit denm_pdu_codec() { };
virtual int encode (const DENM__PDU__Descriptions::DENM& denm, BITSTRING& data);
virtual int decode (const BITSTRING& data, DENM__PDU__Descriptions::DENM&);
explicit denm_pdu_codec(){};
virtual int encode(const DENM__PDU__Descriptions::DENM &denm, BITSTRING &data);
virtual int decode(const BITSTRING &data, DENM__PDU__Descriptions::DENM &);
};
......@@ -11,5 +11,5 @@
#pragma once
using namespace std; // Required for isnan()
#include "LibItsDenm_TypesAndValues.hh"
#include "LibItsDenm_TestSystem.hh"
#include "LibItsDenm_TypesAndValues.hh"
......@@ -2,7 +2,7 @@
#include "loggers.hh"
ethernet_layer::ethernet_layer(const std::string & p_type, const std::string & param) : layer(p_type), _params() {
ethernet_layer::ethernet_layer(const std::string &p_type, const std::string &param) : layer(p_type), _params() {
loggers::get_instance().log(">>> ethernet_layer::ethernet_layer: %s, %s", to_string().c_str(), param.c_str());
// Setup parameters
params::convert(_params, param);
......@@ -21,7 +21,7 @@ ethernet_layer::ethernet_layer(const std::string & p_type, const std::string & p
//_params.log();
}
void ethernet_layer::send_data(OCTETSTRING& data, params& params) {
void ethernet_layer::send_data(OCTETSTRING &data, params &params) {
loggers::get_instance().log_msg(">>> ethernet_layer::send_data: ", data);
OCTETSTRING eth;
......@@ -51,31 +51,31 @@ void ethernet_layer::send_data(OCTETSTRING& data, params& params) {
} else {
eth += str2oct(CHARSTRING(_params[params::eth_type].c_str()));
}
eth += data;
send_to_all_layers(eth, params);
}
void ethernet_layer::receive_data(OCTETSTRING& data, params& params) {
void ethernet_layer::receive_data(OCTETSTRING &data, params &params) {
loggers::get_instance().log_msg(">>> ethernet_layer::receive_data: ", data);
// Extract dest MAC Address
OCTETSTRING dst = OCTETSTRING(6, static_cast<const unsigned char *>(data));
//loggers::get_instance().log_msg("ethernet_layer::receive_data: dst: ", dst);
// loggers::get_instance().log_msg("ethernet_layer::receive_data: dst: ", dst);
// Extract source MAC Address
OCTETSTRING src = OCTETSTRING(6, 6 + static_cast<const unsigned char *>(data));
//loggers::get_instance().log_msg("ethernet_layer::receive_data: src: ", src);
// loggers::get_instance().log_msg("ethernet_layer::receive_data: src: ", src);
// Extract ethertype
OCTETSTRING proto = OCTETSTRING(2, 2 + static_cast<const unsigned char *>(data));
//loggers::get_instance().log_msg("ethernet_layer::receive_data: proto: ", proto);
// loggers::get_instance().log_msg("ethernet_layer::receive_data: proto: ", proto);
data = OCTETSTRING(data.lengthof() - 14, 14 + static_cast<const unsigned char *>(data));
// Update params
CHARSTRING s = oct2str(dst);
params.insert(std::pair<std::string, std::string>(params::mac_dst, std::string(static_cast<const char *>(s))));
s = oct2str(src);
params.insert(std::pair<std::string, std::string>(params::mac_src, std::string(static_cast<const char *>(s))));
//loggers::get_instance().log_msg("ethernet_layer::receive_data: payload for upper layer:", data);
// loggers::get_instance().log_msg("ethernet_layer::receive_data: payload for upper layer:", data);
receive_to_all_layers(data, params);
}
......
......@@ -10,8 +10,8 @@
*/
#pragma once
#include "t_layer.hh"
#include "params.hh"
#include "t_layer.hh"
class ethernet_layer : public layer {
params _params; //! Layer parameters
......@@ -23,11 +23,11 @@ public: //! \publicsection
* \param[in] p_type \todo
* \param[in] p_param \todo
*/
ethernet_layer(const std::string & p_type, const std::string & param);
ethernet_layer(const std::string &p_type, const std::string &param);
/*!
* \brief Default destructor
*/
virtual ~ethernet_layer() {};
virtual ~ethernet_layer(){};
/*!
* \virtual
......@@ -36,7 +36,7 @@ public: //! \publicsection
* \param[in] p_data The data to be sent
* \param[in] p_params Some parameters to overwrite default value of the lower layers parameters
*/
virtual void send_data(OCTETSTRING& data, params& params);
virtual void send_data(OCTETSTRING &data, params &params);
/*!
* \virtual
* \fn void receive_data(OCTETSTRING& data, params& params);
......@@ -44,5 +44,5 @@ public: //! \publicsection
* \param[in] p_data The bytes formated data received
* \param[in] p_params Some lower layers parameters values when data was received
*/
virtual void receive_data(OCTETSTRING& data, params& info);
virtual void receive_data(OCTETSTRING &data, params &info);
}; // End of class ethernet_layer
......@@ -18,9 +18,9 @@
* \class ethernet_layer_factory
* \brief This class provides a factory class to create an ethernet_layer class instance
*/
class ethernet_layer_factory: public layer_factory {
class ethernet_layer_factory : public layer_factory {
static ethernet_layer_factory _f; //! Reference to the unique instance of this class
public: //! \publicsection
public: //! \publicsection
/*!
* \brief Default constructor
* Create a new instance of the ethernet_layer_factory class
......@@ -38,8 +38,5 @@ public: //! \publicsection
* \return 0 on success, -1 otherwise
* \inline
*/
inline virtual layer* create_layer(const std::string& p_type, const std::string& p_param) {
return new ethernet_layer(p_type, p_param);
};
inline virtual layer *create_layer(const std::string &p_type, const std::string &p_param) { return new ethernet_layer(p_type, p_param); };
}; // End of class ethernet_layer_factory
......@@ -12,20 +12,26 @@ class decoding_context {
public:
explicit decoding_context() { reset(); };
~decoding_context() { };
inline void reset() { _next_header = 0xff; _header_type = 0xff; _header_sub_type = 0xff; _lifetime = 0; _length = -1; };
~decoding_context(){};
inline void reset() {
_next_header = 0xff;
_header_type = 0xff;
_header_sub_type = 0xff;
_lifetime = 0;
_length = -1;
};
public:
inline unsigned char get_next_header() { return _next_header; };
inline void set_next_header(const unsigned char p_next_header) { _next_header = p_next_header; };
inline void set_next_header(const unsigned char p_next_header) { _next_header = p_next_header; };
inline unsigned char get_header_type() { return _header_type; };
inline void set_header_type(const unsigned char p_header_type) { _header_type = p_header_type; };
inline void set_header_type(const unsigned char p_header_type) { _header_type = p_header_type; };
inline unsigned char get_header_sub_type() { return _header_sub_type; };
inline void set_header_sub_type(const unsigned char p_header_sub_type) { _header_sub_type = p_header_sub_type; };
inline void set_header_sub_type(const unsigned char p_header_sub_type) { _header_sub_type = p_header_sub_type; };
inline unsigned char get_traffic_class() { return _traffic_class; };
inline void set_traffic_class(const unsigned char p_traffic_class) { _traffic_class = p_traffic_class; };
inline unsigned int get_lifetime() { return _lifetime; };
inline void set_lifetime(const unsigned int p_lifetime) { _lifetime = p_lifetime; };
inline unsigned int get_length() { return _length; };
inline void set_length(const unsigned int p_length) { _length = p_length; };
inline void set_traffic_class(const unsigned char p_traffic_class) { _traffic_class = p_traffic_class; };
inline unsigned int get_lifetime() { return _lifetime; };
inline void set_lifetime(const unsigned int p_lifetime) { _lifetime = p_lifetime; };
inline unsigned int get_length() { return _length; };
inline void set_length(const unsigned int p_length) { _length = p_length; };
}; // End of class decoding_context
......@@ -11,17 +11,23 @@ class encoding_context {
public:
explicit encoding_context() { reset(); }
inline void reset() { _basic_header = 0xff; _next_header = 0xff; _header_type = 0xff; _length_position = -1; _length = -1; }
inline void reset() {
_basic_header = 0xff;
_next_header = 0xff;
_header_type = 0xff;
_length_position = -1;
_length = -1;
}
public:
inline unsigned char get_basic_header() { return _basic_header; };
inline void set_basic_header(const unsigned char p_basic_header) { _basic_header = p_basic_header; };
inline void set_basic_header(const unsigned char p_basic_header) { _basic_header = p_basic_header; };
inline unsigned char get_next_header() { return _next_header; };
inline void set_next_header(const unsigned char p_next_header) { _next_header = p_next_header; };
inline void set_next_header(const unsigned char p_next_header) { _next_header = p_next_header; };
inline unsigned char get_header_type() { return _header_type; };
inline void set_header_type(const unsigned char p_header_type) { _header_type = p_header_type; };
inline unsigned int get_length_position() { return _length_position; };
inline void set_length_position(const unsigned int p_length_position) { _length_position = p_length_position; };
inline unsigned int get_length() { return _length; };
inline void set_length(const unsigned int p_length) { _length = p_length; };
inline void set_header_type(const unsigned char p_header_type) { _header_type = p_header_type; };
inline unsigned int get_length_position() { return _length_position; };
inline void set_length_position(const unsigned int p_length_position) { _length_position = p_length_position; };
inline unsigned int get_length() { return _length; };
inline void set_length(const unsigned int p_length) { _length = p_length; };
}; // End of class encoding_context
......@@ -11,22 +11,22 @@
template <typename T_type> class OPTIONAL;
class TTCN_EncDec;
int geonetworking_codec::encode (const LibItsGeoNetworking__TypesAndValues::GeoNetworkingPdu& msg, OCTETSTRING& data)
{
loggers::get_instance().log_msg(">>> geonetworking_codec::encode (1): ", (const Base_Type&)msg);
int geonetworking_codec::encode(const LibItsGeoNetworking__TypesAndValues::GeoNetworkingPdu &msg, OCTETSTRING &data) {
loggers::get_instance().log_msg(">>> geonetworking_codec::encode (1): ", (const Base_Type &)msg);
TTCN_EncDec::clear_error();
TTCN_Buffer encoding_buffer;
_ec.reset();
encode_(msg, *msg.get_descriptor(), encoding_buffer);
data = OCTETSTRING(encoding_buffer.get_len(), encoding_buffer.get_data());
// Overwrite the payload length
if (_ec.get_length() != (unsigned int)-1) {
loggers::get_instance().log("geonetworking_codec::encode: length=%d - plLength_position = %d - plLength = %d", data.lengthof(), _ec.get_length_position(), _ec.get_length());
unsigned char b[] = { (unsigned char)((_ec.get_length() & 0x0000FF00) >> 8), (unsigned char)_ec.get_length() };
OCTETSTRING rpl(sizeof(b), b);
loggers::get_instance().log("geonetworking_codec::encode: length=%d - plLength_position = %d - plLength = %d", data.lengthof(), _ec.get_length_position(),
_ec.get_length());
unsigned char b[] = {(unsigned char)((_ec.get_length() & 0x0000FF00) >> 8), (unsigned char)_ec.get_length()};
OCTETSTRING rpl(sizeof(b), b);
loggers::get_instance().log_msg("geonetworking_codec::encode: rpl=", rpl);
data = replace(data, _ec.get_length_position(), rpl.lengthof(), rpl);
loggers::get_instance().log_msg("geonetworking_codec::encode: after replace: ", data);
......@@ -37,9 +37,8 @@ int geonetworking_codec::encode (const LibItsGeoNetworking__TypesAndValues::GeoN
return 0;
}
int geonetworking_codec::encode (const LibItsGeoNetworking__TypesAndValues::GnNonSecuredPacket& p_gnNonSecuredPacket, OCTETSTRING& data)
{
loggers::get_instance().log_msg(">>> geonetworking_codec::encode (2): ", (const Base_Type&)p_gnNonSecuredPacket);
int geonetworking_codec::encode(const LibItsGeoNetworking__TypesAndValues::GnNonSecuredPacket &p_gnNonSecuredPacket, OCTETSTRING &data) {
loggers::get_instance().log_msg(">>> geonetworking_codec::encode (2): ", (const Base_Type &)p_gnNonSecuredPacket);
TTCN_EncDec::clear_error();
TTCN_Buffer encoding_buffer;
......@@ -47,9 +46,10 @@ int geonetworking_codec::encode (const LibItsGeoNetworking__TypesAndValues::GnNo
data = OCTETSTRING(encoding_buffer.get_len(), encoding_buffer.get_data());
// Overwrite the payload length
if (_ec.get_length() != (unsigned int)-1) {
loggers::get_instance().log("geonetworking_codec::encode: length=%d - plLength_position = %d - plLength = %d", data.lengthof(), _ec.get_length_position(), _ec.get_length());
unsigned char b[] = { (unsigned char)((_ec.get_length() & 0x0000FF00) >> 8), (unsigned char)_ec.get_length() };
OCTETSTRING rpl(sizeof(b), b);
loggers::get_instance().log("geonetworking_codec::encode: length=%d - plLength_position = %d - plLength = %d", data.lengthof(), _ec.get_length_position(),
_ec.get_length());
unsigned char b[] = {(unsigned char)((_ec.get_length() & 0x0000FF00) >> 8), (unsigned char)_ec.get_length()};
OCTETSTRING rpl(sizeof(b), b);
loggers::get_instance().log_msg("geonetworking_codec::encode: rpl=", rpl);
data = replace(data, _ec.get_length_position(), rpl.lengthof(), rpl);
loggers::get_instance().log_msg("geonetworking_codec::encode: after replace: ", data);
......@@ -60,30 +60,32 @@ int geonetworking_codec::encode (const LibItsGeoNetworking__TypesAndValues::GnNo
return 0;
}
int geonetworking_codec::encode_ (const Base_Type& type, const TTCN_Typedescriptor_t& field_descriptor, TTCN_Buffer& encoding_buffer)
{
//loggers::get_instance().log(">>> geonetworking_codec::encode_: processing %s/%s", type.get_descriptor()->name, field_descriptor.name);
//loggers::get_instance().log_msg(">>> geonetworking_codec::encode_: ", type);
int geonetworking_codec::encode_(const Base_Type &type, const TTCN_Typedescriptor_t &field_descriptor, TTCN_Buffer &encoding_buffer) {
// loggers::get_instance().log(">>> geonetworking_codec::encode_: processing %s/%s", type.get_descriptor()->name, field_descriptor.name);
// loggers::get_instance().log_msg(">>> geonetworking_codec::encode_: ", type);
if (dynamic_cast<const Record_Type *>(&type) != NULL) {
const Record_Type& r = (const Record_Type &)type;
//loggers::get_instance().log("geonetworking_codec::encode_: processing Record_Type %s", r.get_descriptor()->name);
for(int i = 0; i < r.get_count(); i++) {
//loggers::get_instance().log("geonetworking_codec::encode_: processing %s/%s/%s - %d (1 ==> use dynamic_cast<const OPTIONAL<...>) - %d", r.fld_name(i), r.fld_descr(i)->name, r.get_at(i)->get_descriptor()->name, r.get_at(i)->is_optional(), r.get_at(i)->is_present());
const Record_Type &r = (const Record_Type &)type;
// loggers::get_instance().log("geonetworking_codec::encode_: processing Record_Type %s", r.get_descriptor()->name);
for (int i = 0; i < r.get_count(); i++) {
// loggers::get_instance().log("geonetworking_codec::encode_: processing %s/%s/%s - %d (1 ==> use dynamic_cast<const OPTIONAL<...>) - %d", r.fld_name(i),
// r.fld_descr(i)->name, r.get_at(i)->get_descriptor()->name, r.get_at(i)->is_optional(), r.get_at(i)->is_present());
if (r.get_at(i)->is_present()) {
if ((_ec.get_basic_header() == 0x02) && (std::string(r.fld_descr(i)->name).compare("@LibItsGeoNetworking_TypesAndValues.GeoNetworkingPacket.packet") == 0)) { // Encoding secured GeoNetworking packet, unsecured GN message was already encoded using encvalue
//loggers::get_instance().log("geonetworking_codec::encode_: Skip it");
if ((_ec.get_basic_header() == 0x02) && (std::string(r.fld_descr(i)->name).compare("@LibItsGeoNetworking_TypesAndValues.GeoNetworkingPacket.packet") ==
0)) { // Encoding secured GeoNetworking packet, unsecured GN message was already encoded using encvalue
// loggers::get_instance().log("geonetworking_codec::encode_: Skip it");
continue;
}
if (encode_(*r.get_at(i), *r.fld_descr(i), encoding_buffer) == -1) {
//loggers::get_instance().warning("geonetworking_codec::encode_: -1 result code returned");
// loggers::get_instance().warning("geonetworking_codec::encode_: -1 result code returned");
return -1;
}
}
} // End of 'for' statement
} else if (std::string(type.get_descriptor()->name).compare("@LibItsGeoNetworking_TypesAndValues.ExtendedHeader") == 0) {
const OPTIONAL<LibItsGeoNetworking__TypesAndValues::ExtendedHeader> &v = dynamic_cast<const OPTIONAL<LibItsGeoNetworking__TypesAndValues::ExtendedHeader> &>(type);
//loggers::get_instance().log("geonetworking_codec::encode_: ExtendedHeader present: %d", v.is_present());
const OPTIONAL<LibItsGeoNetworking__TypesAndValues::ExtendedHeader> &v =
dynamic_cast<const OPTIONAL<LibItsGeoNetworking__TypesAndValues::ExtendedHeader> &>(type);
// loggers::get_instance().log("geonetworking_codec::encode_: ExtendedHeader present: %d", v.is_present());
if (v.is_present()) {
if (encode_extendedHeader(static_cast<const LibItsGeoNetworking__TypesAndValues::ExtendedHeader &>(*v.get_opt_value()), encoding_buffer) == -1) {
loggers::get_instance().warning("geonetworking_codec::encode_: -1 result code returned");
......@@ -91,91 +93,92 @@ int geonetworking_codec::encode_ (const Base_Type& type, const TTCN_Typedescript
}
}
} else if (std::string(field_descriptor.name).compare("@LibItsGeoNetworking_TypesAndValues.GnNonSecuredPacket.payload") == 0) {
const OPTIONAL<LibItsGeoNetworking__TypesAndValues::GnRawPayload> &v = dynamic_cast<const OPTIONAL<LibItsGeoNetworking__TypesAndValues::GnRawPayload> &>(type);
//loggers::get_instance().log("geonetworking_codec::encode_: GnRawPayload present: %d", v.is_present());
const OPTIONAL<LibItsGeoNetworking__TypesAndValues::GnRawPayload> &v =
dynamic_cast<const OPTIONAL<LibItsGeoNetworking__TypesAndValues::GnRawPayload> &>(type);
// loggers::get_instance().log("geonetworking_codec::encode_: GnRawPayload present: %d", v.is_present());
if (v.is_present()) {
const LibItsGeoNetworking__TypesAndValues::GnRawPayload& p = static_cast<const LibItsGeoNetworking__TypesAndValues::GnRawPayload &>(*v.get_opt_value());
if (encode_(p, *p.get_descriptor()/*LibItsGeoNetworking__TypesAndValues::GnRawPayload_descr_*/, encoding_buffer) == -1) {
const LibItsGeoNetworking__TypesAndValues::GnRawPayload &p = static_cast<const LibItsGeoNetworking__TypesAndValues::GnRawPayload &>(*v.get_opt_value());
if (encode_(p, *p.get_descriptor() /*LibItsGeoNetworking__TypesAndValues::GnRawPayload_descr_*/, encoding_buffer) == -1) {
loggers::get_instance().warning("geonetworking_codec::encode_: -1 result code returned");
return -1;
}
// Store playload length and continue encoding
_ec.set_length(p.lengthof());
//loggers::get_instance().log("geonetworking_codec::encode_: Storing payload length %d for %s", _ec.get_length(), p.get_descriptor()->name);
// loggers::get_instance().log("geonetworking_codec::encode_: Storing payload length %d for %s", _ec.get_length(), p.get_descriptor()->name);
}
} else if (std::string(field_descriptor.name).compare("@EtsiTs103097Module.EtsiTs103097Data") == 0) {
const EtsiTs103097Module::EtsiTs103097Data& ieee_1609dot2_data = static_cast<const EtsiTs103097Module::EtsiTs103097Data&>(type);
//loggers::get_instance().log_msg("geonetworking_codec::encode_: Encode secured message= ", ieee_1609dot2_data);
const EtsiTs103097Module::EtsiTs103097Data &ieee_1609dot2_data = static_cast<const EtsiTs103097Module::EtsiTs103097Data &>(type);
// loggers::get_instance().log_msg("geonetworking_codec::encode_: Encode secured message= ", ieee_1609dot2_data);
etsi_ts103097_data_codec codec;
OCTETSTRING os;
OCTETSTRING os;
codec.encode(ieee_1609dot2_data, os);
if (os.lengthof() == 0) {
loggers::get_instance().warning("geonetworking_codec::encode_: Failed to encode EtsiTs103097Data");
return -1;
}
//loggers::get_instance().log_msg("geonetworking_codec::encode_: ", os);
// loggers::get_instance().log_msg("geonetworking_codec::encode_: ", os);
encoding_buffer.put_string(os);
} else {
//loggers::get_instance().log("geonetworking_codec::encode_ (else): processing type %s/%s", type.get_descriptor()->name, field_descriptor.name);
// loggers::get_instance().log("geonetworking_codec::encode_ (else): processing type %s/%s", type.get_descriptor()->name, field_descriptor.name);
if (std::string(field_descriptor.name).compare("@LibItsGeoNetworking_TypesAndValues.BasicHeader.nextHeader") == 0) {
// Store NextHeader field value and continue encoding
_ec.set_basic_header((unsigned int)dynamic_cast<const Enum_Type &>(type).as_int());
//loggers::get_instance().log("geonetworking_codec::encode_: Storing basic_header %d for %s", _ec.get_next_header(), field_descriptor.name);
// loggers::get_instance().log("geonetworking_codec::encode_: Storing basic_header %d for %s", _ec.get_next_header(), field_descriptor.name);
} else if (std::string(field_descriptor.name).compare("@LibItsGeoNetworking_TypesAndValues.CommonHeader.nextHeader") == 0) {
// Store NextHeader field value and continue encoding
_ec.set_next_header((unsigned int)dynamic_cast<const Enum_Type &>(type).as_int());
//loggers::get_instance().log("geonetworking_codec::encode_: Storing next_header %d for %s", _ec.get_next_header(), field_descriptor.name);
// loggers::get_instance().log("geonetworking_codec::encode_: Storing next_header %d for %s", _ec.get_next_header(), field_descriptor.name);
} else if (std::string(field_descriptor.name).compare("@LibItsGeoNetworking_TypesAndValues.CommonHeader.headerType") == 0) {
// Store HeaderType field value and continue encoding
_ec.set_header_type((unsigned int)dynamic_cast<const Enum_Type &>(type).as_int());
//loggers::get_instance().log("geonetworking_codec::encode_: Storing header_type %d for %s", _ec.get_header_type(), field_descriptor.name);
} else if (std::string(field_descriptor.name).compare("@LibItsGeoNetworking_TypesAndValues.CommonHeader.plLength") == 0) {
// loggers::get_instance().log("geonetworking_codec::encode_: Storing header_type %d for %s", _ec.get_header_type(), field_descriptor.name);
} else if (std::string(field_descriptor.name).compare("@LibItsGeoNetworking_TypesAndValues.CommonHeader.plLength") == 0) {
// Store TTCN_Buffer position and continue encoding
_ec.set_length_position(encoding_buffer.get_len());
//loggers::get_instance().log("geonetworking_codec::encode_: Storing position %d for %s", _ec.get_length_position(), field_descriptor.name);
// loggers::get_instance().log("geonetworking_codec::encode_: Storing position %d for %s", _ec.get_length_position(), field_descriptor.name);
}
type.encode(field_descriptor, encoding_buffer, TTCN_EncDec::CT_RAW);
}
//loggers::get_instance().log_to_hexa("<<< geonetworking_codec::encode_: ", encoding_buffer);
// loggers::get_instance().log_to_hexa("<<< geonetworking_codec::encode_: ", encoding_buffer);
return 0;
}
int geonetworking_codec::decode (const OCTETSTRING& data, LibItsGeoNetworking__TypesAndValues::GeoNetworkingPdu& msg, params* params)
{
int geonetworking_codec::decode(const OCTETSTRING &data, LibItsGeoNetworking__TypesAndValues::GeoNetworkingPdu &msg, params *params) {
TTCN_EncDec::clear_error();
TTCN_Buffer decoding_buffer(data);
_dc.reset();
_params = params;
loggers::get_instance().log_to_hexa(">>> geonetworking_codec::decode: decoding_buffer=", decoding_buffer);
decode_(msg, *msg.get_descriptor(), decoding_buffer);
loggers::get_instance().log("geonetworking_codec::decode: After decoding, payload: plLength=%d", _dc.get_length());
// Set layer parameters
if (_params != NULL) {
(*_params)[params::gn_next_header] = std::to_string((unsigned int)_dc.get_next_header());
(*_params)[params::gn_header_type] = std::to_string((unsigned int)_dc.get_header_type());
(*_params)[params::gn_next_header] = std::to_string((unsigned int)_dc.get_next_header());
(*_params)[params::gn_header_type] = std::to_string((unsigned int)_dc.get_header_type());
(*_params)[params::gn_header_sub_type] = std::to_string((unsigned int)_dc.get_header_sub_type());
(*_params)[params::gn_traffic_class] = std::to_string((unsigned int)_dc.get_traffic_class());
(*_params)[params::gn_lifetime] = std::to_string(_dc.get_lifetime());
(*_params)[params::gn_traffic_class] = std::to_string((unsigned int)_dc.get_traffic_class());
(*_params)[params::gn_lifetime] = std::to_string(_dc.get_lifetime());
params->log();
}
loggers::get_instance().log_msg("<<< geonetworking_codec::decode: ", (const Base_Type&)msg);
loggers::get_instance().log_msg("<<< geonetworking_codec::decode: ", (const Base_Type &)msg);
return 0;
}
int geonetworking_codec::decode_ (Base_Type& type, const TTCN_Typedescriptor_t& field_descriptor, TTCN_Buffer& decoding_buffer)
{
//loggers::get_instance().log(">>> geonetworking_codec::decode_: processing %s/%s (%d,%d,%p)", type.get_descriptor()->name, field_descriptor.name, decoding_buffer.get_len(), decoding_buffer.get_pos(), decoding_buffer.get_read_data());
int geonetworking_codec::decode_(Base_Type &type, const TTCN_Typedescriptor_t &field_descriptor, TTCN_Buffer &decoding_buffer) {
// loggers::get_instance().log(">>> geonetworking_codec::decode_: processing %s/%s (%d,%d,%p)", type.get_descriptor()->name, field_descriptor.name,
// decoding_buffer.get_len(), decoding_buffer.get_pos(), decoding_buffer.get_read_data());
if (dynamic_cast<Record_Type *>(&type) != NULL) {
Record_Type& r = (Record_Type &)type;
//loggers::get_instance().log("geonetworking_codec::decode_: processing Record_Type %s", r.get_descriptor()->name);
for(int i = 0; i < r.get_count(); i++) {
//loggers::get_instance().log("geonetworking_codec::decode_: processing %s/%s/%s", r.fld_name(i), r.fld_descr(i)->name, r.get_at(i)->get_descriptor()->name);
Record_Type &r = (Record_Type &)type;
// loggers::get_instance().log("geonetworking_codec::decode_: processing Record_Type %s", r.get_descriptor()->name);
for (int i = 0; i < r.get_count(); i++) {
// loggers::get_instance().log("geonetworking_codec::decode_: processing %s/%s/%s", r.fld_name(i), r.fld_descr(i)->name,
// r.get_at(i)->get_descriptor()->name);
if (decode_(*dynamic_cast<Base_Type *>(r.get_at(i)), *(r.fld_descr(i)), decoding_buffer) == -1) {
loggers::get_instance().warning("geonetworking_codec::decode_: -1 result code returned");
return -1;
......@@ -183,32 +186,34 @@ int geonetworking_codec::decode_ (Base_Type& type, const TTCN_Typedescriptor_t&
} // End of 'for' statement
// Save data for upper layer
if (std::string(r.get_descriptor()->name).compare("@LibItsGeoNetworking_TypesAndValues.Lifetime") == 0) {
LibItsGeoNetworking__TypesAndValues::Lifetime& l = static_cast<LibItsGeoNetworking__TypesAndValues::Lifetime&>(r);
unsigned int base = 0;
LibItsGeoNetworking__TypesAndValues::Lifetime &l = static_cast<LibItsGeoNetworking__TypesAndValues::Lifetime &>(r);
unsigned int base = 0;
switch (l.ltBase().as_int()) {
case LibItsGeoNetworking__TypesAndValues::LtBase::e__50ms:
base = 50;
break;
case LibItsGeoNetworking__TypesAndValues::LtBase::e__1s:
base = 1000;
break;
case LibItsGeoNetworking__TypesAndValues::LtBase::e__10s:
base = 10000;
break;
case LibItsGeoNetworking__TypesAndValues::LtBase::e__100s:
base = 100000;
break;
case LibItsGeoNetworking__TypesAndValues::LtBase::e__50ms:
base = 50;
break;
case LibItsGeoNetworking__TypesAndValues::LtBase::e__1s:
base = 1000;
break;
case LibItsGeoNetworking__TypesAndValues::LtBase::e__10s:
base = 10000;
break;
case LibItsGeoNetworking__TypesAndValues::LtBase::e__100s:
base = 100000;
break;
} // End of 'switch' statement
_dc.set_lifetime(base * static_cast<unsigned int>(l.multiplier()));
//loggers::get_instance().log("geonetworking_codec::decode_: Lifetime calculus: %d - %s", _dc.get_lifetime(), std::to_string(_dc.get_lifetime()).c_str());
// loggers::get_instance().log("geonetworking_codec::decode_: Lifetime calculus: %d - %s", _dc.get_lifetime(),
// std::to_string(_dc.get_lifetime()).c_str());
} else if (std::string(type.get_descriptor()->name).compare("@LibItsGeoNetworking_TypesAndValues.TrafficClass") == 0) {
LibItsGeoNetworking__TypesAndValues::TrafficClass& t = static_cast<LibItsGeoNetworking__TypesAndValues::TrafficClass&>(r);
LibItsGeoNetworking__TypesAndValues::TrafficClass &t = static_cast<LibItsGeoNetworking__TypesAndValues::TrafficClass &>(r);
_dc.set_traffic_class((t.scf().as_int() << 7) | (t.channelOffload() << 6) | (t.tcId() & 0x3f)); // ETSI EN 302 636-4-1 chapter 8.7.5
}
} else if (std::string(type.get_descriptor()->name).compare("@IEEE1609dot2.Ieee1609Dot2Data") == 0) {
dynamic_cast<OPTIONAL<IEEE1609dot2::Ieee1609Dot2Data> &>(type).set_to_omit(); // TODO Add security support
} else {
//loggers::get_instance().log("geonetworking_codec::decode_ (else): processing type %s/%s - optional:%d", type.get_descriptor()->name, field_descriptor.name, type.is_optional());
// loggers::get_instance().log("geonetworking_codec::decode_ (else): processing type %s/%s - optional:%d", type.get_descriptor()->name,
// field_descriptor.name, type.is_optional());
if (std::string(field_descriptor.name).compare("@LibItsGeoNetworking_TypesAndValues.CommonHeader.nextHeader") == 0) {
// Decode NextHeader data structure
type.decode(field_descriptor, decoding_buffer, TTCN_EncDec::CT_RAW);
......@@ -222,42 +227,42 @@ int geonetworking_codec::decode_ (Base_Type& type, const TTCN_Typedescriptor_t&
decode_extendedHeader(e, decoding_buffer);
if (e.is_bound()) {
dynamic_cast<OPTIONAL<LibItsGeoNetworking__TypesAndValues::ExtendedHeader> &>(type) = OPTIONAL<LibItsGeoNetworking__TypesAndValues::ExtendedHeader>(e);
//loggers::get_instance().log_msg("geonetworking_codec::decode_: Set OPTIONAL to ", type);
// loggers::get_instance().log_msg("geonetworking_codec::decode_: Set OPTIONAL to ", type);
} else {
//loggers::get_instance().log("geonetworking_codec::decode_: Set OPTIONAL to omit");
// loggers::get_instance().log("geonetworking_codec::decode_: Set OPTIONAL to omit");
dynamic_cast<OPTIONAL<LibItsGeoNetworking__TypesAndValues::ExtendedHeader> &>(type).set_to_omit();
}
} else if (std::string(field_descriptor.name).compare("@LibItsGeoNetworking_TypesAndValues.GnNonSecuredPacket.payload") == 0) {
// Decode raw payload data structure
OCTETSTRING s(decoding_buffer.get_len() - decoding_buffer.get_pos(), decoding_buffer.get_data() + decoding_buffer.get_pos());
//loggers::get_instance().log_msg("geonetworking_codec::decode_: s=", s);
const unsigned char * p = static_cast<const unsigned char *>(s);
// loggers::get_instance().log_msg("geonetworking_codec::decode_: s=", s);
const unsigned char *p = static_cast<const unsigned char *>(s);
if (p == NULL) {
loggers::get_instance().warning("geonetworking_codec::encode_: Static cast error");
return -1;
}
// Align the payload length with the specified plLenght value
//loggers::get_instance().log("geonetworking_codec::decode_: Payload: Decoded payload length: %d", _dc.get_length());
// loggers::get_instance().log("geonetworking_codec::decode_: Payload: Decoded payload length: %d", _dc.get_length());
OCTETSTRING os;
if (_dc.get_length() != 0) {
if ((unsigned char)s.lengthof() <= _dc.get_length()) {
os = OCTETSTRING(s.lengthof(), p);
os = OCTETSTRING(s.lengthof(), p);
(*_params)[params::gn_payload] = static_cast<const char *>(oct2str(os));
} else {
os = OCTETSTRING(_dc.get_length(), p);
os = OCTETSTRING(_dc.get_length(), p);
(*_params)[params::gn_payload] = static_cast<const char *>(oct2str(os));
}
} else {
os = OCTETSTRING(0, nullptr);
os = OCTETSTRING(0, nullptr);
(*_params)[params::gn_payload] = "";
}
//loggers::get_instance().log_msg("geonetworking_codec::decode_: Payload: os: ", os);
//loggers::get_instance().log("geonetworking_codec::decode_: Payload: '%s'", (*_params)[params::gn_payload].c_str());
// loggers::get_instance().log_msg("geonetworking_codec::decode_: Payload: os: ", os);
// loggers::get_instance().log("geonetworking_codec::decode_: Payload: '%s'", (*_params)[params::gn_payload].c_str());
if (os.lengthof() != 0) {
dynamic_cast<OPTIONAL<LibItsGeoNetworking__TypesAndValues::GnRawPayload> &>(type) = OPTIONAL<LibItsGeoNetworking__TypesAndValues::GnRawPayload>(os);
//loggers::get_instance().log_msg("geonetworking_codec::decode_: Set OPTIONAL<GnRawPayload> to ", type);
// loggers::get_instance().log_msg("geonetworking_codec::decode_: Set OPTIONAL<GnRawPayload> to ", type);
} else {
//loggers::get_instance().log("geonetworking_codec::decode_: Set OPTIONAL<GnRawPayload> to omit");
// loggers::get_instance().log("geonetworking_codec::decode_: Set OPTIONAL<GnRawPayload> to omit");
dynamic_cast<OPTIONAL<LibItsGeoNetworking__TypesAndValues::GnRawPayload> &>(type).set_to_omit();
}
} else if (std::string(field_descriptor.name).compare("@LibItsGeoNetworking_TypesAndValues.CommonHeader.plLength") == 0) {
......@@ -270,138 +275,143 @@ int geonetworking_codec::decode_ (Base_Type& type, const TTCN_Typedescriptor_t&
}
}
//loggers::get_instance().log_msg("<<< geonetworking_codec::decode_: ", type);
//loggers::get_instance().log_to_hexa("<<< geonetworking_codec::decode_: decoding_buffer=", decoding_buffer);
// loggers::get_instance().log_msg("<<< geonetworking_codec::decode_: ", type);
// loggers::get_instance().log_to_hexa("<<< geonetworking_codec::decode_: decoding_buffer=", decoding_buffer);
return 0;
}
int geonetworking_codec::encode_extendedHeader(const LibItsGeoNetworking__TypesAndValues::ExtendedHeader& u, TTCN_Buffer& encoding_buffer) {
//loggers::get_instance().log(">>> geonetworking_codec::encode_extendedHeader: processing %s", u.get_descriptor()->name);
int geonetworking_codec::encode_extendedHeader(const LibItsGeoNetworking__TypesAndValues::ExtendedHeader &u, TTCN_Buffer &encoding_buffer) {
// loggers::get_instance().log(">>> geonetworking_codec::encode_extendedHeader: processing %s", u.get_descriptor()->name);
int result = -1;
switch (u.get_selection()) {
case LibItsGeoNetworking__TypesAndValues::ExtendedHeader::UNBOUND_VALUE:
TTCN_error("geonetworking_codec::encode_extendedHeader: Invalid selection in unbound union");
break;
case LibItsGeoNetworking__TypesAndValues::ExtendedHeader::ALT_geoUnicastHeader:
//loggers::get_instance().log("geonetworking_codec::encode_extendedHeader: processing type %s", u.geoUnicastHeader().get_descriptor()->name);
result = encode_(u.geoUnicastHeader(), *u.geoUnicastHeader().get_descriptor(), encoding_buffer);
break;
case LibItsGeoNetworking__TypesAndValues::ExtendedHeader::ALT_tsbHeader:
//loggers::get_instance().log("geonetworking_codec::encode_extendedHeader: processing type %s", u.tsbHeader().get_descriptor()->name);
result = encode_(u.tsbHeader(), *u.tsbHeader().get_descriptor(), encoding_buffer);
break;
case LibItsGeoNetworking__TypesAndValues::ExtendedHeader::ALT_shbHeader:
//loggers::get_instance().log("geonetworking_codec::encode_extendedHeader: processing type %s", u.shbHeader().get_descriptor()->name);
result = encode_(u.shbHeader(), *u.shbHeader().get_descriptor(), encoding_buffer);
break;
case LibItsGeoNetworking__TypesAndValues::ExtendedHeader::ALT_geoBroadcastHeader:
//loggers::get_instance().log("geonetworking_codec::encode_extendedHeader: processing type %s", u.geoBroadcastHeader().get_descriptor()->name);
result = encode_(u.geoBroadcastHeader(), *u.geoBroadcastHeader().get_descriptor(), encoding_buffer);
break;
case LibItsGeoNetworking__TypesAndValues::ExtendedHeader::ALT_geoAnycastHeader:
//loggers::get_instance().log("geonetworking_codec::encode_extendedHeader: processing type %s", u.geoAnycastHeader().get_descriptor()->name);
result = encode_(u.geoAnycastHeader(), *u.geoAnycastHeader().get_descriptor(), encoding_buffer);
break;
case LibItsGeoNetworking__TypesAndValues::ExtendedHeader::ALT_beaconHeader:
//loggers::get_instance().log("geonetworking_codec::encode_extendedHeader: processing type %s", u.beaconHeader().get_descriptor()->name);
result = encode_(u.beaconHeader(), *u.beaconHeader().get_descriptor(), encoding_buffer);
break;
case LibItsGeoNetworking__TypesAndValues::ExtendedHeader::ALT_anyHeader:
//loggers::get_instance().log("geonetworking_codec::encode_extendedHeader: processing type %s", u.anyHeader().get_descriptor()->name);
result = encode_(u.anyHeader(), *u.anyHeader().get_descriptor(), encoding_buffer);
break;
case LibItsGeoNetworking__TypesAndValues::ExtendedHeader::ALT_lsRequestHeader:
//loggers::get_instance().log("geonetworking_codec::encode_extendedHeader: processing type %s", u.lsRequestHeader().get_descriptor()->name);
result = encode_(u.lsRequestHeader(), *u.lsRequestHeader().get_descriptor(), encoding_buffer);
break;
case LibItsGeoNetworking__TypesAndValues::ExtendedHeader::ALT_lsReplyHeader:
//loggers::get_instance().log("geonetworking_codec::encode_extendedHeader: processing type %s", u.lsReplyHeader().get_descriptor()->name);
result = encode_(u.lsReplyHeader(), *u.lsReplyHeader().get_descriptor(), encoding_buffer);
break;
default: TTCN_error("geonetworking_codec::encode_extendedHeader: Invalid selection in union is_bound");
case LibItsGeoNetworking__TypesAndValues::ExtendedHeader::UNBOUND_VALUE:
TTCN_error("geonetworking_codec::encode_extendedHeader: Invalid selection in unbound union");
break;
case LibItsGeoNetworking__TypesAndValues::ExtendedHeader::ALT_geoUnicastHeader:
// loggers::get_instance().log("geonetworking_codec::encode_extendedHeader: processing type %s", u.geoUnicastHeader().get_descriptor()->name);
result = encode_(u.geoUnicastHeader(), *u.geoUnicastHeader().get_descriptor(), encoding_buffer);
break;
case LibItsGeoNetworking__TypesAndValues::ExtendedHeader::ALT_tsbHeader:
// loggers::get_instance().log("geonetworking_codec::encode_extendedHeader: processing type %s", u.tsbHeader().get_descriptor()->name);
result = encode_(u.tsbHeader(), *u.tsbHeader().get_descriptor(), encoding_buffer);
break;
case LibItsGeoNetworking__TypesAndValues::ExtendedHeader::ALT_shbHeader:
// loggers::get_instance().log("geonetworking_codec::encode_extendedHeader: processing type %s", u.shbHeader().get_descriptor()->name);
result = encode_(u.shbHeader(), *u.shbHeader().get_descriptor(), encoding_buffer);
break;
case LibItsGeoNetworking__TypesAndValues::ExtendedHeader::ALT_geoBroadcastHeader:
// loggers::get_instance().log("geonetworking_codec::encode_extendedHeader: processing type %s", u.geoBroadcastHeader().get_descriptor()->name);
result = encode_(u.geoBroadcastHeader(), *u.geoBroadcastHeader().get_descriptor(), encoding_buffer);
break;
case LibItsGeoNetworking__TypesAndValues::ExtendedHeader::ALT_geoAnycastHeader:
// loggers::get_instance().log("geonetworking_codec::encode_extendedHeader: processing type %s", u.geoAnycastHeader().get_descriptor()->name);
result = encode_(u.geoAnycastHeader(), *u.geoAnycastHeader().get_descriptor(), encoding_buffer);
break;
case LibItsGeoNetworking__TypesAndValues::ExtendedHeader::ALT_beaconHeader:
// loggers::get_instance().log("geonetworking_codec::encode_extendedHeader: processing type %s", u.beaconHeader().get_descriptor()->name);
result = encode_(u.beaconHeader(), *u.beaconHeader().get_descriptor(), encoding_buffer);
break;
case LibItsGeoNetworking__TypesAndValues::ExtendedHeader::ALT_anyHeader:
// loggers::get_instance().log("geonetworking_codec::encode_extendedHeader: processing type %s", u.anyHeader().get_descriptor()->name);
result = encode_(u.anyHeader(), *u.anyHeader().get_descriptor(), encoding_buffer);
break;
case LibItsGeoNetworking__TypesAndValues::ExtendedHeader::ALT_lsRequestHeader:
// loggers::get_instance().log("geonetworking_codec::encode_extendedHeader: processing type %s", u.lsRequestHeader().get_descriptor()->name);
result = encode_(u.lsRequestHeader(), *u.lsRequestHeader().get_descriptor(), encoding_buffer);
break;
case LibItsGeoNetworking__TypesAndValues::ExtendedHeader::ALT_lsReplyHeader:
// loggers::get_instance().log("geonetworking_codec::encode_extendedHeader: processing type %s", u.lsReplyHeader().get_descriptor()->name);
result = encode_(u.lsReplyHeader(), *u.lsReplyHeader().get_descriptor(), encoding_buffer);
break;
default:
TTCN_error("geonetworking_codec::encode_extendedHeader: Invalid selection in union is_bound");
} // End of 'switch' statement
return result;
}
int geonetworking_codec::decode_headerTST(LibItsGeoNetworking__TypesAndValues::HeaderTST& u, TTCN_Buffer& decoding_buffer) {
//loggers::get_instance().log(">>> geonetworking_codec::decode_headerTST: processing %s", u.get_descriptor()->name);
int geonetworking_codec::decode_headerTST(LibItsGeoNetworking__TypesAndValues::HeaderTST &u, TTCN_Buffer &decoding_buffer) {
// loggers::get_instance().log(">>> geonetworking_codec::decode_headerTST: processing %s", u.get_descriptor()->name);
// Decode HeaderTST data structure
_dc.set_header_type(*(decoding_buffer.get_data() + decoding_buffer.get_pos()) >> 4);
_dc.set_header_sub_type(*(decoding_buffer.get_data() + decoding_buffer.get_pos()) & 0x0F);
//loggers::get_instance().log("geonetworking_codec::decode_: headerTST selectors: _dc.header_type = %d - _dc.header_sub_type = %d", _dc.get_header_type(), _dc.get_header_sub_type());
//LibItsGeoNetworking__TypesAndValues::HeaderTST & u = dynamic_cast<LibItsGeoNetworking__TypesAndValues::HeaderTST &>(u);
// loggers::get_instance().log("geonetworking_codec::decode_: headerTST selectors: _dc.header_type = %d - _dc.header_sub_type = %d", _dc.get_header_type(),
// _dc.get_header_sub_type()); LibItsGeoNetworking__TypesAndValues::HeaderTST & u = dynamic_cast<LibItsGeoNetworking__TypesAndValues::HeaderTST &>(u);
switch (_dc.get_header_type()) {
case LibItsGeoNetworking__TypesAndValues::HeaderType::e__geoUnicast:
decode_(u.geoUnicastHdr(), *u.geoUnicastHdr().get_descriptor(), decoding_buffer);
break;
case LibItsGeoNetworking__TypesAndValues::HeaderType::e__topologicallyScopedBroadcast:
decode_(u.tsbHdr(), *u.tsbHdr().get_descriptor(), decoding_buffer);
break;
case LibItsGeoNetworking__TypesAndValues::HeaderType::e__geoBroadcast:
decode_(u.geoBroadcastHdr(), *u.geoBroadcastHdr().get_descriptor(), decoding_buffer);
break;
case LibItsGeoNetworking__TypesAndValues::HeaderType::e__geoAnycast:
decode_(u.geoAnycastHdr(), *u.geoAnycastHdr().get_descriptor(), decoding_buffer);
break;
case LibItsGeoNetworking__TypesAndValues::HeaderType::e__beacon:
decode_(u.beaconHdr(), *u.beaconHdr().get_descriptor(), decoding_buffer);
break;
case LibItsGeoNetworking__TypesAndValues::HeaderType::e__locationService:
decode_(u.lsHdr(), *u.lsHdr().get_descriptor(), decoding_buffer);
break;
case LibItsGeoNetworking__TypesAndValues::HeaderType::e__any:
decode_(u.anyHdr(), *u.anyHdr().get_descriptor(), decoding_buffer);
break;
default:
TTCN_error("geonetworking_codec::decode_: Not processed, _dc.header_type = %d - _dc.header_sub_type = %d", _dc.get_header_type(), _dc.get_header_sub_type());
case LibItsGeoNetworking__TypesAndValues::HeaderType::e__geoUnicast:
decode_(u.geoUnicastHdr(), *u.geoUnicastHdr().get_descriptor(), decoding_buffer);
break;
case LibItsGeoNetworking__TypesAndValues::HeaderType::e__topologicallyScopedBroadcast:
decode_(u.tsbHdr(), *u.tsbHdr().get_descriptor(), decoding_buffer);
break;
case LibItsGeoNetworking__TypesAndValues::HeaderType::e__geoBroadcast:
decode_(u.geoBroadcastHdr(), *u.geoBroadcastHdr().get_descriptor(), decoding_buffer);
break;
case LibItsGeoNetworking__TypesAndValues::HeaderType::e__geoAnycast:
decode_(u.geoAnycastHdr(), *u.geoAnycastHdr().get_descriptor(), decoding_buffer);
break;
case LibItsGeoNetworking__TypesAndValues::HeaderType::e__beacon:
decode_(u.beaconHdr(), *u.beaconHdr().get_descriptor(), decoding_buffer);
break;
case LibItsGeoNetworking__TypesAndValues::HeaderType::e__locationService:
decode_(u.lsHdr(), *u.lsHdr().get_descriptor(), decoding_buffer);
break;
case LibItsGeoNetworking__TypesAndValues::HeaderType::e__any:
decode_(u.anyHdr(), *u.anyHdr().get_descriptor(), decoding_buffer);
break;
default:
TTCN_error("geonetworking_codec::decode_: Not processed, _dc.header_type = %d - _dc.header_sub_type = %d", _dc.get_header_type(),
_dc.get_header_sub_type());
} // End of 'switch' statement
return 0;
}
int geonetworking_codec::decode_extendedHeader(LibItsGeoNetworking__TypesAndValues::ExtendedHeader& u, TTCN_Buffer& decoding_buffer) {
//loggers::get_instance().log(">>> geonetworking_codec::decode_extendedHeader: processing %s", u.get_descriptor()->name);
int geonetworking_codec::decode_extendedHeader(LibItsGeoNetworking__TypesAndValues::ExtendedHeader &u, TTCN_Buffer &decoding_buffer) {
// loggers::get_instance().log(">>> geonetworking_codec::decode_extendedHeader: processing %s", u.get_descriptor()->name);
switch (_dc.get_header_type()) {
case LibItsGeoNetworking__TypesAndValues::HeaderType::e__geoUnicast:
decode_(u.geoUnicastHeader(), *u.geoUnicastHeader().get_descriptor(), decoding_buffer);
break;
case LibItsGeoNetworking__TypesAndValues::HeaderType::e__topologicallyScopedBroadcast:
if (_dc.get_header_sub_type() == LibItsGeoNetworking__TypesAndValues::HeaderSubTypeTSB::e__multiHop) {
decode_(u.tsbHeader(), *u.tsbHeader().get_descriptor(), decoding_buffer);
} else if (_dc.get_header_sub_type() == LibItsGeoNetworking__TypesAndValues::HeaderSubTypeTSB::e__singleHop) {
decode_(u.shbHeader(), *u.shbHeader().get_descriptor(), decoding_buffer);
} else {
TTCN_error("geonetworking_codec::decode_headerTST: TSB subtype not processed, See ETSI EN 302 636-4-1 Clause 9.7.4 Encoding of the HT and HST fields");
}
break;
case LibItsGeoNetworking__TypesAndValues::HeaderType::e__geoBroadcast:
decode_(u.geoBroadcastHeader(), *u.geoBroadcastHeader().get_descriptor(), decoding_buffer);
break;
case LibItsGeoNetworking__TypesAndValues::HeaderType::e__geoAnycast:
decode_(u.geoAnycastHeader(), *u.geoAnycastHeader().get_descriptor(), decoding_buffer);
break;
case LibItsGeoNetworking__TypesAndValues::HeaderType::e__beacon:
decode_(u.beaconHeader(), *u.beaconHeader().get_descriptor(), decoding_buffer);
break;
case LibItsGeoNetworking__TypesAndValues::HeaderType::e__locationService:
if (_dc.get_header_sub_type() == LibItsGeoNetworking__TypesAndValues::HeaderSubTypeLs::e__lsRequest) {
decode_(u.lsRequestHeader(), *u.lsRequestHeader().get_descriptor(), decoding_buffer);
} else if (_dc.get_header_sub_type() == LibItsGeoNetworking__TypesAndValues::HeaderSubTypeLs::e__lsReply) {
decode_(u.lsReplyHeader(), *u.lsReplyHeader().get_descriptor(), decoding_buffer);
} else {
TTCN_error("geonetworking_codec::decode_headerTST: Location service subtype not processed, See ETSI EN 302 636-4-1 Clause 9.7.4 Encoding of the HT and HST fields");
}
break;
case LibItsGeoNetworking__TypesAndValues::HeaderType::e__any:
decode_(u.anyHeader(), *u.anyHeader().get_descriptor(), decoding_buffer);
break;
default:
TTCN_error("geonetworking_codec::decode_headerTST: Not processed, _dc.header_type = %d - _dc.header_sub_type = %d, See ETSI EN 302 636-4-1 Clause 9.7.4 Encoding of the HT and HST fields", _dc.get_header_type(), _dc.get_header_sub_type());
case LibItsGeoNetworking__TypesAndValues::HeaderType::e__geoUnicast:
decode_(u.geoUnicastHeader(), *u.geoUnicastHeader().get_descriptor(), decoding_buffer);
break;
case LibItsGeoNetworking__TypesAndValues::HeaderType::e__topologicallyScopedBroadcast:
if (_dc.get_header_sub_type() == LibItsGeoNetworking__TypesAndValues::HeaderSubTypeTSB::e__multiHop) {
decode_(u.tsbHeader(), *u.tsbHeader().get_descriptor(), decoding_buffer);
} else if (_dc.get_header_sub_type() == LibItsGeoNetworking__TypesAndValues::HeaderSubTypeTSB::e__singleHop) {
decode_(u.shbHeader(), *u.shbHeader().get_descriptor(), decoding_buffer);
} else {
TTCN_error("geonetworking_codec::decode_headerTST: TSB subtype not processed, See ETSI EN 302 636-4-1 Clause 9.7.4 Encoding of the HT and HST fields");
}
break;
case LibItsGeoNetworking__TypesAndValues::HeaderType::e__geoBroadcast:
decode_(u.geoBroadcastHeader(), *u.geoBroadcastHeader().get_descriptor(), decoding_buffer);
break;
case LibItsGeoNetworking__TypesAndValues::HeaderType::e__geoAnycast:
decode_(u.geoAnycastHeader(), *u.geoAnycastHeader().get_descriptor(), decoding_buffer);
break;
case LibItsGeoNetworking__TypesAndValues::HeaderType::e__beacon:
decode_(u.beaconHeader(), *u.beaconHeader().get_descriptor(), decoding_buffer);
break;
case LibItsGeoNetworking__TypesAndValues::HeaderType::e__locationService:
if (_dc.get_header_sub_type() == LibItsGeoNetworking__TypesAndValues::HeaderSubTypeLs::e__lsRequest) {
decode_(u.lsRequestHeader(), *u.lsRequestHeader().get_descriptor(), decoding_buffer);
} else if (_dc.get_header_sub_type() == LibItsGeoNetworking__TypesAndValues::HeaderSubTypeLs::e__lsReply) {
decode_(u.lsReplyHeader(), *u.lsReplyHeader().get_descriptor(), decoding_buffer);
} else {
TTCN_error("geonetworking_codec::decode_headerTST: Location service subtype not processed, See ETSI EN 302 636-4-1 Clause 9.7.4 Encoding of the HT and "
"HST fields");
}
break;
case LibItsGeoNetworking__TypesAndValues::HeaderType::e__any:
decode_(u.anyHeader(), *u.anyHeader().get_descriptor(), decoding_buffer);
break;
default:
TTCN_error("geonetworking_codec::decode_headerTST: Not processed, _dc.header_type = %d - _dc.header_sub_type = %d, See ETSI EN 302 636-4-1 Clause 9.7.4 "
"Encoding of the HT and HST fields",
_dc.get_header_type(), _dc.get_header_sub_type());
} // End of 'switch' statement
return 0;
......
......@@ -5,8 +5,8 @@
#include "codec.hh"
#include "params.hh"
#include "encoding_context.hh"
#include "decoding_context.hh"
#include "encoding_context.hh"
class Base_Type;
class TTCN_Typedescriptor_t;
......@@ -18,7 +18,7 @@ namespace LibItsGeoNetworking__TypesAndValues {
class HeaderTST;
class ExtendedHeader;
class DecodedPayload;
};
}; // namespace LibItsGeoNetworking__TypesAndValues
namespace LibItsSecurity__TypesAndValues {
class SecuredMessage;
......@@ -29,19 +29,21 @@ class geonetworking_codec : public codec<LibItsGeoNetworking__TypesAndValues::Ge
encoding_context _ec;
decoding_context _dc;
int encode_ (const Base_Type& type, const TTCN_Typedescriptor_t& field_descriptor, TTCN_Buffer& encoding_buffer);
int encode_extendedHeader(const LibItsGeoNetworking__TypesAndValues::ExtendedHeader& u, TTCN_Buffer& encoding_buffer);
int encode_(const Base_Type &type, const TTCN_Typedescriptor_t &field_descriptor, TTCN_Buffer &encoding_buffer);
int encode_extendedHeader(const LibItsGeoNetworking__TypesAndValues::ExtendedHeader &u, TTCN_Buffer &encoding_buffer);
int decode_ (Base_Type& type, const TTCN_Typedescriptor_t& field_descriptor, TTCN_Buffer& decoding_buffer);
int decode_headerTST(LibItsGeoNetworking__TypesAndValues::HeaderTST& u, TTCN_Buffer& decoding_buffer);
int decode_extendedHeader(LibItsGeoNetworking__TypesAndValues::ExtendedHeader& u, TTCN_Buffer& decodin_buffer);
int decode_(Base_Type &type, const TTCN_Typedescriptor_t &field_descriptor, TTCN_Buffer &decoding_buffer);
int decode_headerTST(LibItsGeoNetworking__TypesAndValues::HeaderTST &u, TTCN_Buffer &decoding_buffer);
int decode_extendedHeader(LibItsGeoNetworking__TypesAndValues::ExtendedHeader &u, TTCN_Buffer &decodin_buffer);
public:
explicit geonetworking_codec() : codec<LibItsGeoNetworking__TypesAndValues::GeoNetworkingPdu, LibItsGeoNetworking__TypesAndValues::GeoNetworkingPdu>(), _ec(), _dc() { };
virtual ~geonetworking_codec() { };
virtual int encode (const LibItsGeoNetworking__TypesAndValues::GeoNetworkingPdu& msg, OCTETSTRING& data);
virtual int decode (const OCTETSTRING& data, LibItsGeoNetworking__TypesAndValues::GeoNetworkingPdu& msg, params* params = NULL);
int encode (const LibItsGeoNetworking__TypesAndValues::GnNonSecuredPacket& p_gnNonSecuredPacket, OCTETSTRING& data); // TODO Duplicate code with virtual encode, to be enhanced
}; // End of class geonetworking_codec
explicit geonetworking_codec()
: codec<LibItsGeoNetworking__TypesAndValues::GeoNetworkingPdu, LibItsGeoNetworking__TypesAndValues::GeoNetworkingPdu>(), _ec(), _dc(){};
virtual ~geonetworking_codec(){};
virtual int encode(const LibItsGeoNetworking__TypesAndValues::GeoNetworkingPdu &msg, OCTETSTRING &data);
virtual int decode(const OCTETSTRING &data, LibItsGeoNetworking__TypesAndValues::GeoNetworkingPdu &msg, params *params = NULL);
int encode(const LibItsGeoNetworking__TypesAndValues::GnNonSecuredPacket &p_gnNonSecuredPacket,
OCTETSTRING & data); // TODO Duplicate code with virtual encode, to be enhanced
}; // End of class geonetworking_codec
#include <thread>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <thread>
#include "geonetworking_types.hh"
......@@ -19,7 +19,11 @@
using namespace LibItsGeoNetworking__TypesAndValues;
geonetworking_layer::geonetworking_layer(const std::string & p_type, const std::string & p_param) : t_layer<LibItsGeoNetworking__TestSystem::GeoNetworkingPort>(p_type), _params(), _codec(), _beacon(nullptr), _gbc_packet(nullptr), _shb_packet(nullptr), _tsb_packet(nullptr),_uni_packet(nullptr), _ls_reply(nullptr), _location_table(), _pass_beacon_table(), _device_mode{false}, _secured_mode{false}, _encrypted_mode{false}, _enable_security_checks{false}, _sendData(), _timerid{0}, _sev{0}, _its{0}, _freq_nanosecs(0), _mask{0}, _sa{0}, _sequence_number{0}, _latitude{0}, _longitude{0} {
geonetworking_layer::geonetworking_layer(const std::string &p_type, const std::string &p_param)
: t_layer<LibItsGeoNetworking__TestSystem::GeoNetworkingPort>(p_type), _params(), _codec(), _beacon(nullptr), _gbc_packet(nullptr), _shb_packet(nullptr),
_tsb_packet(nullptr), _uni_packet(nullptr), _ls_reply(nullptr), _location_table(),
_pass_beacon_table(), _device_mode{false}, _secured_mode{false}, _encrypted_mode{false}, _enable_security_checks{false},
_sendData(), _timerid{0}, _sev{0}, _its{0}, _freq_nanosecs(0), _mask{0}, _sa{0}, _sequence_number{0}, _latitude{0}, _longitude{0} {
loggers::get_instance().log(">>> geonetworking_layer::geonetworking_layer: %s, %s", to_string().c_str(), p_param.c_str());
init(p_type, p_param);
......@@ -51,9 +55,9 @@ geonetworking_layer::~geonetworking_layer() {
}
} // End of destructor
void geonetworking_layer::init(const std::string & p_type, const std::string & p_param) {
void geonetworking_layer::init(const std::string &p_type, const std::string &p_param) {
loggers::get_instance().log(">>> geonetworking_layer::init: %s, %s", to_string().c_str(), p_param.c_str());
// Setup parameters
params::convert(_params, p_param);
// Sanity checks
......@@ -71,36 +75,36 @@ void geonetworking_layer::init(const std::string & p_type, const std::string & p
ll_address = str2oct(CHARSTRING(it->second.c_str()));
}
INTEGER distanceA = 1000; // 1km
it = _params.find(params::distanceA);
it = _params.find(params::distanceA);
if (it != _params.cend()) {
distanceA = converter::get_instance().string_to_int(it->second);
}
INTEGER distanceB = 1000; // 1Km
it = _params.find(params::distanceB);
it = _params.find(params::distanceB);
if (it != _params.cend()) {
distanceB = converter::get_instance().string_to_int(it->second);
}
INTEGER angle = 0;
it = _params.find(params::angle);
it = _params.find(params::angle);
if (it != _params.cend()) {
angle = converter::get_instance().string_to_int(it->second);
}
INTEGER station_type = 5; // passangerCar
it = _params.find(params::station_type);
it = _params.find(params::station_type);
if (it != _params.cend()) {
station_type = converter::get_instance().string_to_int(it->second);
}
INTEGER country = 0;
it = _params.find(params::country);
it = _params.find(params::country);
if (it != _params.cend()) {
country = converter::get_instance().string_to_int(it->second);
}
INTEGER type_of_address = 1; // Manual
it = _params.find(params::type_of_address);
it = _params.find(params::type_of_address);
if (it != _params.cend()) {
type_of_address = converter::get_instance().string_to_int(it->second);
}
it = _params.find(params::device_mode);
if (it != _params.cend()) {
_device_mode = (1 == converter::get_instance().string_to_int(it->second));
......@@ -121,7 +125,7 @@ void geonetworking_layer::init(const std::string & p_type, const std::string & p
if (it != _params.cend()) {
_enable_security_checks = (1 == converter::get_instance().string_to_int(it->second));
}
// Add broadcast address if needed
it = _params.find(params::its_aid);
if (it == _params.cend()) {
......@@ -131,7 +135,7 @@ void geonetworking_layer::init(const std::string & p_type, const std::string & p
if (it == _params.cend()) {
_params.insert(std::pair<std::string, std::string>(std::string("mac_bc"), "FFFFFFFFFFFF"));
}
// Set up default security parameters value
if (_secured_mode || _encrypted_mode) {
loggers::get_instance().log("geonetworking_layer::geonetworking_layer: Setup secured mode");
......@@ -147,12 +151,13 @@ void geonetworking_layer::init(const std::string & p_type, const std::string & p
}
// Fill packet templates
fill_gbc_packet(ll_address, _latitude, _longitude, distanceA, distanceB, angle);// TODO Check if GeoBroadcastArea lat/lon are identical to lat/lon of the Test System
fill_gbc_packet(ll_address, _latitude, _longitude, distanceA, distanceB,
angle); // TODO Check if GeoBroadcastArea lat/lon are identical to lat/lon of the Test System
fill_shb_packet(ll_address);
fill_tsb_packet(ll_address);
fill_uni_packet(ll_address);
fill_ls_reply(ll_address);
// Register this object for AdapterControlPort
loggers::get_instance().log("geonetworking_layer::geonetworking_layer: Register %s/%p", p_type.c_str(), this);
registration<geonetworking_layer>::get_instance().add_item(p_type, this);
......@@ -161,7 +166,7 @@ void geonetworking_layer::init(const std::string & p_type, const std::string & p
base_time::get_instance().set_leap_delay_us(4 * 1000000); // TODO Set it as parameter
} // End of init_params
void geonetworking_layer::sendMsg(const LibItsGeoNetworking__TestSystem::GeoNetworkingReq& p, params& params) {
void geonetworking_layer::sendMsg(const LibItsGeoNetworking__TestSystem::GeoNetworkingReq &p, params &params) {
loggers::get_instance().log(">>> geonetworking_layer::sendMsg");
// Encode GeoNetworking PDU
......@@ -170,14 +175,14 @@ void geonetworking_layer::sendMsg(const LibItsGeoNetworking__TestSystem::GeoNetw
send_data(data, _params);
}
void geonetworking_layer::send_data(OCTETSTRING& data, params& params) {
void geonetworking_layer::send_data(OCTETSTRING &data, params &params) {
loggers::get_instance().log_msg(">>> geonetworking_layer::send_data: ", data);
params.log();
if (_device_mode) { // Need to build a GN packet
params[params::certificate] = _params[params::certificate];
params[params::hash] = _params[params::hash];
params[params::signature] = _params[params::signature]; // TODO Should be removed
params[params::hash] = _params[params::hash];
params[params::signature] = _params[params::signature]; // TODO Should be removed
if (build_geonetworking_pdu(data, params) != 0) {
return;
}
......@@ -187,7 +192,7 @@ void geonetworking_layer::send_data(OCTETSTRING& data, params& params) {
return;
}
}
// TODO To be removed
while (_sendData.try_lock() == FALSE) {
// not ready yet
......@@ -198,25 +203,27 @@ void geonetworking_layer::send_data(OCTETSTRING& data, params& params) {
loggers::get_instance().log("<<< geonetworking_layer::send_data");
}
const TTCN_RAWdescriptor_t _intx_raw_= {RAW_INTX,SG_NO,ORDER_MSB,ORDER_MSB,ORDER_LSB,ORDER_MSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN};
const TTCN_Typedescriptor_t _intx_descr_={"IntX", NULL, &_intx_raw_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE};
const TTCN_RAWdescriptor_t _intx_raw_ = {RAW_INTX, SG_NO, ORDER_MSB, ORDER_MSB, ORDER_LSB, ORDER_MSB, EXT_BIT_NO, ORDER_LSB, ORDER_LSB,
TOP_BIT_INHERITED, 0, 0, 0, 8, 0, NULL, -1, CharCoding::UNKNOWN};
const TTCN_Typedescriptor_t _intx_descr_ = {"IntX", NULL, &_intx_raw_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE};
void geonetworking_layer::receive_data(OCTETSTRING& data, params& params) {
void geonetworking_layer::receive_data(OCTETSTRING &data, params &params) {
loggers::get_instance().log_msg(">>> geonetworking_layer::receive_data: ", data);
// Check security mode
IEEE1609dot2::Ieee1609Dot2Data ieee_1609dot2_data;
IEEE1609dot2::Ieee1609Dot2Data ieee_1609dot2_data;
LibItsGeoNetworking__TypesAndValues::BasicHeader basic_header;
decode_basic_header(data, basic_header);
if ((int)basic_header.nextHeader() == 2) { // Verify and extract the GeoNetworking Secured Packet as specified in ETSI EN 302 636-4-1 V1.3.1 (2017-08) Clause 9.6.1 Composition of the Basic Header
unsigned int basic_header_len = 4;// FIXME How to retrive the BasicHeader length basic_header.get_descriptor()->raw->fieldlength / 8;
if ((int)basic_header.nextHeader() == 2) { // Verify and extract the GeoNetworking Secured Packet as specified in ETSI EN 302 636-4-1 V1.3.1 (2017-08)
// Clause 9.6.1 Composition of the Basic Header
unsigned int basic_header_len = 4; // FIXME How to retrive the BasicHeader length basic_header.get_descriptor()->raw->fieldlength / 8;
loggers::get_instance().log("geonetworking_layer::receive_data: basic_header_len = %d", basic_header_len);
// Verify and extract the GeoNetworking Secured Packet as specified in ETSI EN 302 636-4-1 V1.3.1 (2017-08) Clause 9.4 GeoNetworking Secured Packet
OCTETSTRING unsecured_gn_payload;
OCTETSTRING secured_data = OCTETSTRING(data.lengthof() - basic_header_len, static_cast<const unsigned char*>(data) + basic_header_len);
OCTETSTRING secured_data = OCTETSTRING(data.lengthof() - basic_header_len, static_cast<const unsigned char *>(data) + basic_header_len);
///////////////////
// FIXME Check what to do with this!
if (*static_cast<const unsigned char*>(secured_data) == 0x02) { // This is the old Security version format, discard it
if (*static_cast<const unsigned char *>(secured_data) == 0x02) { // This is the old Security version format, discard it
/*loggers::get_instance().warning("geonetworking_layer::receive_data: Security error");
if (_enable_security_checks) {
return;
......@@ -241,11 +248,11 @@ void geonetworking_layer::receive_data(OCTETSTRING& data, params& params) {
//payload length
if(n > (int)buf.get_read_len()){
loggers::get_instance().warning("geonetworking_layer::receive_data: Broken security payload");
return;
return;
}
unsecured_gn_payload = OCTETSTRING(n, buf.get_read_data());
}*/
} else if (*static_cast<const unsigned char*>(secured_data) != 0x03) {
} else if (*static_cast<const unsigned char *>(secured_data) != 0x03) {
loggers::get_instance().warning("geonetworking_layer::receive_data: Security error, wrong protocol number, discard it anyway");
if (_enable_security_checks) {
return;
......@@ -253,7 +260,8 @@ void geonetworking_layer::receive_data(OCTETSTRING& data, params& params) {
return;
} else {
///////////////////
if (security_services::get_instance().verify_and_extract_gn_payload(secured_data, _enable_security_checks, ieee_1609dot2_data, unsecured_gn_payload, params) != 0) {
if (security_services::get_instance().verify_and_extract_gn_payload(secured_data, _enable_security_checks, ieee_1609dot2_data, unsecured_gn_payload,
params) != 0) {
loggers::get_instance().warning("geonetworking_layer::receive_data: Security error");
if (_enable_security_checks) {
return;
......@@ -262,9 +270,9 @@ void geonetworking_layer::receive_data(OCTETSTRING& data, params& params) {
}
// Update data
loggers::get_instance().log_msg("geonetworking_layer::receive_data: Unsecured payload: ", unsecured_gn_payload);
data = OCTETSTRING(basic_header_len, static_cast<const unsigned char*>(data)) + unsecured_gn_payload;
data = OCTETSTRING(basic_header_len, static_cast<const unsigned char *>(data)) + unsecured_gn_payload;
}
// Decode the payload
loggers::get_instance().log_msg("geonetworking_layer::receive_data: Geonetworking payload to decode: ", data);
LibItsGeoNetworking__TestSystem::GeoNetworkingInd ind;
......@@ -275,11 +283,11 @@ void geonetworking_layer::receive_data(OCTETSTRING& data, params& params) {
ind.msgIn().gnPacket().securedMsg() = OPTIONAL<IEEE1609dot2::Ieee1609Dot2Data>(ieee_1609dot2_data);
} // else, nothing to do
// Update context
const LibItsGeoNetworking__TypesAndValues::LongPosVector* sopv = nullptr;
const LibItsGeoNetworking__TypesAndValues::GnNonSecuredPacket& p = ind.msgIn().gnPacket().packet();
const LibItsGeoNetworking__TypesAndValues::HeaderTST& htst = p.commonHeader().headerTST();
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();
const LibItsGeoNetworking__TypesAndValues::ExtendedHeader &ex = p.extendedHeader();
if (htst.ischosen(LibItsGeoNetworking__TypesAndValues::HeaderTST::ALT_beaconHdr)) { // Receive a beacon
sopv = &ex.beaconHeader().srcPosVector();
} else if (htst.ischosen(LibItsGeoNetworking__TypesAndValues::HeaderTST::ALT_tsbHdr)) { // Receive a topologicallyScopeBroadcast
......@@ -290,26 +298,26 @@ void geonetworking_layer::receive_data(OCTETSTRING& data, params& params) {
}
} else if (htst.ischosen(LibItsGeoNetworking__TypesAndValues::HeaderTST::ALT_geoBroadcastHdr)) {
sopv = &ex.geoBroadcastHeader().srcPosVector();
} else if (htst.ischosen(LibItsGeoNetworking__TypesAndValues::HeaderTST::ALT_lsHdr)) { // Receive a location service
} else if (htst.ischosen(LibItsGeoNetworking__TypesAndValues::HeaderTST::ALT_lsHdr)) { // Receive a location service
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 in case of non GN test suite
if (_device_mode) {
// Update _ls_reply
ExtendedHeader* eh = static_cast<ExtendedHeader *>(_ls_reply->gnPacket().packet().extendedHeader().get_opt_value());
ExtendedHeader *eh = static_cast<ExtendedHeader *>(_ls_reply->gnPacket().packet().extendedHeader().get_opt_value());
if (eh != nullptr) {
// Update sequence number
eh->lsReplyHeader().seqNumber() = _sequence_number++;
// Update destination
eh->lsReplyHeader().dstPosVector().gnAddr() = sopv->gnAddr();
eh->lsReplyHeader().dstPosVector().latitude() = sopv->latitude();
eh->lsReplyHeader().dstPosVector().gnAddr() = sopv->gnAddr();
eh->lsReplyHeader().dstPosVector().latitude() = sopv->latitude();
eh->lsReplyHeader().dstPosVector().longitude() = sopv->longitude();
// Update timestamp
eh->lsReplyHeader().srcPosVector().timestamp__().set_long_long_val(base_time::get_instance().get_its_current_time_mod_ms());
eh->lsReplyHeader().dstPosVector().timestamp__() = eh->lsReplyHeader().srcPosVector().timestamp__();
loggers::get_instance().log_msg("geonetworking_layer::receive_data: ", *_ls_reply);
// send it
// Encode GeoNetworking PDU
OCTETSTRING os;
......@@ -342,19 +350,19 @@ void geonetworking_layer::receive_data(OCTETSTRING& data, params& params) {
sopv = &ex.geoUnicastHeader().srcPosVector();
} // else, nothing to do
loggers::get_instance().log("geonetworking_layer::receive_data: sopv is bound: %d", sopv->is_bound());
if(sopv->is_bound()) {
const LibItsGeoNetworking__TypesAndValues::LongPosVector& lpv = *sopv;
if (sopv->is_bound()) {
const LibItsGeoNetworking__TypesAndValues::LongPosVector &lpv = *sopv;
_location_table.add_entry(lpv);
}
}
// By default incoming beacons are filtered by the test adapter
if (htst.ischosen(LibItsGeoNetworking__TypesAndValues::HeaderTST::ALT_beaconHdr)) {
loggers::get_instance().log_msg("geonetworking_layer::receive_data: Pass beaconing filtering: ", sopv->gnAddr().mid());
if (_pass_beacon_table.empty()) { // Discard beacon
loggers::get_instance().log("geonetworking_layer::receive_data: Pass beaconing table empty, discard it");
return;
} else { // Check beacon filter for StartPassBeaconing/Stop
} else { // Check beacon filter for StartPassBeaconing/Stop
if (!_pass_beacon_table.has_entry(sopv->gnAddr().mid())) { // Discard beacon
loggers::get_instance().log_msg("geonetworking_layer::receive_data: Not in pass beaconing table, discard it", *sopv);
return;
......@@ -392,7 +400,7 @@ void geonetworking_layer::receive_data(OCTETSTRING& data, params& params) {
} else {
ind.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()) {
......@@ -402,26 +410,24 @@ void geonetworking_layer::receive_data(OCTETSTRING& data, params& params) {
} else {
loggers::get_instance().warning("geonetworking_layer::receive_data: No payload to pass to upper layers");
}
// Pass it to the ports
to_all_upper_ports(ind, params);
}
OCTETSTRING geonetworking_layer::trigger_ac_event(OCTETSTRING& data, params& params)
{
OCTETSTRING geonetworking_layer::trigger_ac_event(OCTETSTRING &data, params &params) {
loggers::get_instance().log_to_hexa(">>> geonetworking_layer::trigger_ac_event: ", data);
return int2oct(0, 2);
return int2oct(0, 2);
} // End of trigger_ac_event method
void geonetworking_layer::start_beaconing() {
loggers::get_instance().log(">>> geonetworking_layer::start_beaconing");
//loggers::get_instance().log_msg("geonetworking_layer::start_beaconing: _beacon=", *_beacon);
// loggers::get_instance().log_msg("geonetworking_layer::start_beaconing: _beacon=", *_beacon);
// Establish handler for timer signal
loggers::get_instance().log("geonetworking_layer::start_beaconing: Establishing handler for signal %d\n", _signal_id);
_sa.sa_flags = SA_SIGINFO;
_sa.sa_flags = SA_SIGINFO;
_sa.sa_sigaction = timer_irq_sigalrm_handler;
sigemptyset(&_sa.sa_mask);
if (sigaction(_signal_id, &_sa, nullptr) == -1) {
......@@ -433,25 +439,25 @@ void geonetworking_layer::start_beaconing() {
sigaddset(&_mask, _signal_id);
if (sigprocmask(SIG_SETMASK, &_mask, nullptr) == -1) {
loggers::get_instance().error("geonetworking_layer::start_beaconing: Sigprocmask failure: %d", errno);
}
// Create the timer
_sev.sigev_notify = SIGEV_SIGNAL;
_sev.sigev_signo = _signal_id; // Use signal alarm
_sev.sigev_value.sival_ptr = this; // The geonetworking_layer object address
}
// Create the timer
_sev.sigev_notify = SIGEV_SIGNAL;
_sev.sigev_signo = _signal_id; // Use signal alarm
_sev.sigev_value.sival_ptr = this; // The geonetworking_layer object address
if (timer_create(CLOCK_REALTIME, &_sev, &_timerid) == -1) {
loggers::get_instance().error("geonetworking_layer::start_beaconing: Timer failure: %d", errno);
}
loggers::get_instance().log("geonetworking_layer::start_beaconing: timer ID is 0x%x\n", (long)_timerid);
// Start the timer
unsigned int expiry = 1000; // Default expiry time 1000ms
params::const_iterator i = _params.find("expiry");
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(), nullptr, 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;
_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, nullptr) == -1) {
loggers::get_instance().error("geonetworking_layer::start_beaconing: Sigprocmask failure: %d", errno);
......@@ -463,7 +469,7 @@ void geonetworking_layer::start_beaconing() {
}
} // End of start_beaconing method
void geonetworking_layer::start_beaconing(const LibItsGeoNetworking__TypesAndValues::GeoNetworkingPdu& p_beacon) {
void geonetworking_layer::start_beaconing(const LibItsGeoNetworking__TypesAndValues::GeoNetworkingPdu &p_beacon) {
loggers::get_instance().log_msg(">>> geonetworking_layer::start_beaconing", p_beacon);
// Initialize the beacon
......@@ -477,33 +483,33 @@ void geonetworking_layer::start_beaconing(const LibItsGeoNetworking__TypesAndVal
void geonetworking_layer::stop_beaconing() {
loggers::get_instance().log(">>> geonetworking_layer::stop_beaconing");
// Block timer signal temporarily
loggers::get_instance().log("geonetworking_layer::stop_beaconing: Blocking signal %d\n", _signal_id);
sigemptyset(&_mask);
sigaddset(&_mask, _signal_id);
if (sigprocmask(SIG_SETMASK, &_mask, nullptr) == -1) {
loggers::get_instance().error("geonetworking_layer::stop_beaconing: Sigprocmask failure: %d", errno);
}
}
timer_delete(_timerid);
_timerid = 0;
} // End of stop_beaconing method
void geonetworking_layer::send_beacon() {
loggers::get_instance().log(">>> geonetworking_layer::send_beacon");
ExtendedHeader* eh = static_cast<ExtendedHeader *>(_beacon->gnPacket().packet().extendedHeader().get_opt_value());
ExtendedHeader *eh = static_cast<ExtendedHeader *>(_beacon->gnPacket().packet().extendedHeader().get_opt_value());
if (eh == nullptr) {
loggers::get_instance().error("geonetworking_layer::send_beacon: Wrong cast");
}
// Update timestamp
eh->beaconHeader().srcPosVector().timestamp__().set_long_long_val((unsigned int)base_time::get_instance().get_its_current_time_mod_ms());
//loggers::get_instance().log_msg("geonetworking_layer::send_beacon: ", *_beacon);
// loggers::get_instance().log_msg("geonetworking_layer::send_beacon: ", *_beacon);
// 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());
params params(_params);
params params(_params);
if (_secured_mode) { // Apply Security
if (build_secured_pdu(data, _params) != 0) {
return;
......@@ -517,14 +523,14 @@ void geonetworking_layer::send_beacon() {
} // End of 'while' statement
send_to_all_layers(data, params);
_sendData.unlock();
//loggers::get_instance().log("<<< geonetworking_layer::send_beacon");
// loggers::get_instance().log("<<< geonetworking_layer::send_beacon");
} // End of send_beacon method
void geonetworking_layer::start_pass_beaconing(const LibItsGeoNetworking__TypesAndValues::BeaconHeader& p_beacon) {
void geonetworking_layer::start_pass_beaconing(const LibItsGeoNetworking__TypesAndValues::BeaconHeader &p_beacon) {
loggers::get_instance().log_msg(">>> geonetworking_layer::start_pass_beaconing", p_beacon);
const LibItsGeoNetworking__TypesAndValues::LongPosVector& lpv = p_beacon.srcPosVector();
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
......@@ -536,7 +542,7 @@ void geonetworking_layer::stop_pass_beaconing() {
_pass_beacon_table.reset();
} // End of stop_pass_beaconing method
int geonetworking_layer::enable_secured_mode(const std::string& p_certificate_id, const boolean p_enforce_security) {
int geonetworking_layer::enable_secured_mode(const std::string &p_certificate_id, const boolean p_enforce_security) {
loggers::get_instance().log(">>> geonetworking_layer::enable_secured_mode: '%s' - %x", p_certificate_id.c_str(), p_enforce_security);
loggers::get_instance().log("geonetworking_layer::enable_secured_mode: _secured_mode = %x", _secured_mode);
......@@ -545,7 +551,7 @@ int geonetworking_layer::enable_secured_mode(const std::string& p_certificate_id
_secured_mode = true;
setup_secured_mode();
}
_enable_security_checks = p_enforce_security;
_enable_security_checks = p_enforce_security;
params::const_iterator it = _params.find(params::certificate);
if (it == _params.cend()) {
_params.insert(std::pair<std::string, std::string>(std::string("certificate"), p_certificate_id));
......@@ -553,22 +559,21 @@ int geonetworking_layer::enable_secured_mode(const std::string& p_certificate_id
_params[params::certificate] = p_certificate_id;
}
loggers::get_instance().log("geonetworking_layer::enable_secured_mode: Certificate to be used: '%s'", _params[params::certificate].c_str());
return 0;
}
int geonetworking_layer::disable_secured_mode() {
loggers::get_instance().log(">>> geonetworking_layer::disable_secured_mode");
_secured_mode = false;
_secured_mode = false;
_enable_security_checks = false;
return 0;
}
const LongPosVector* geonetworking_layer::get_lpv(const GN__Address& p_gn_address)
{
const LongPosVector *geonetworking_layer::get_lpv(const GN__Address &p_gn_address) {
loggers::get_instance().log_msg(">>> geonetworking_layer::get_lpv", p_gn_address);
const LongPosVector* lpv = nullptr;
const LongPosVector *lpv = nullptr;
if (_location_table.has_entry(p_gn_address.mid())) {
lpv = _location_table.get_entry(p_gn_address.mid());
}
......@@ -576,374 +581,161 @@ const LongPosVector* geonetworking_layer::get_lpv(const GN__Address& p_gn_addres
} // End of get_lpv
const LibItsGeoNetworking__TypesAndValues::BasicHeader geonetworking_layer::fill_basic_header() const {
return LibItsGeoNetworking__TypesAndValues::BasicHeader(
1, // GeoNetworking version
BasicNextHeader(
BasicNextHeader::e__commonHeader
),
0,
Lifetime(
4,
LtBase(LtBase::e__50ms)
),
1
);
return LibItsGeoNetworking__TypesAndValues::BasicHeader(1, // GeoNetworking version
BasicNextHeader(BasicNextHeader::e__commonHeader), 0, Lifetime(4, LtBase(LtBase::e__50ms)), 1);
}
void geonetworking_layer::fill_beacon(const OCTETSTRING& p_ll_address, const INTEGER p_station_type, const INTEGER p_country, const INTEGER type_of_address)
{
void geonetworking_layer::fill_beacon(const OCTETSTRING &p_ll_address, const INTEGER p_station_type, const INTEGER p_country, const INTEGER type_of_address) {
_beacon = new GeoNetworkingPdu();
HeaderTST h;
h.beaconHdr() = BeaconHeaderType(
HeaderType(HeaderType::e__beacon),
0
);
h.beaconHdr() = BeaconHeaderType(HeaderType(HeaderType::e__beacon), 0);
ExtendedHeader eh;
eh.beaconHeader() = BeaconHeader(
LongPosVector(
GN__Address(
TypeOfAddress((TypeOfAddress)type_of_address),
StationType((StationType)p_station_type),
p_country,
p_ll_address
),
0,
_latitude,
_longitude,
int2bit(0, 1),
0,
0
)
);
eh.beaconHeader() =
BeaconHeader(LongPosVector(GN__Address(TypeOfAddress((TypeOfAddress)type_of_address), StationType((StationType)p_station_type), p_country, p_ll_address), 0,
_latitude, _longitude, int2bit(0, 1), 0, 0));
_beacon->basicHeader() = fill_basic_header();
_beacon->gnPacket().packet() = GnNonSecuredPacket(
CommonHeader(
NextHeader(
NextHeader::e__any
),
0,
h,
TrafficClass(
SCF(SCF::e__scfEnabled),
ChannelOffload(ChannelOffload::e__choffDisabled),
0
),
int2bit(0, 8),
0,
1,
0
),
OPTIONAL<ExtendedHeader>(eh),
OPTIONAL<GnRawPayload>()
);
_beacon->gnPacket().packet() =
GnNonSecuredPacket(CommonHeader(NextHeader(NextHeader::e__any), 0, h,
TrafficClass(SCF(SCF::e__scfEnabled), 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("geonetworking_layer::fill_beacon: beacon value: ", *_beacon);
// loggers::get_instance().log_msg("geonetworking_layer::fill_beacon: beacon value: ", *_beacon);
} // End of fill_beacon method
void geonetworking_layer::fill_gbc_packet(const OCTETSTRING& p_ll_address, const INTEGER& p_geoAreaPosLatitude, const INTEGER& p_geoAreaPosLongitude, const INTEGER& p_distanceA, const INTEGER& p_distanceB, const INTEGER& p_angle)
{
void geonetworking_layer::fill_gbc_packet(const OCTETSTRING &p_ll_address, const INTEGER &p_geoAreaPosLatitude, const INTEGER &p_geoAreaPosLongitude,
const INTEGER &p_distanceA, const INTEGER &p_distanceB, const INTEGER &p_angle) {
_gbc_packet = new GeoNetworkingPdu();
HeaderTST h;
h.geoBroadcastHdr() = GeoBroadcastHeaderType(
HeaderType(HeaderType::e__geoBroadcast),
HeaderSubTypeGeoBroadcast(HeaderSubTypeGeoBroadcast::e__geoBroadcastElip)
);
h.geoBroadcastHdr() =
GeoBroadcastHeaderType(HeaderType(HeaderType::e__geoBroadcast), HeaderSubTypeGeoBroadcast(HeaderSubTypeGeoBroadcast::e__geoBroadcastElip));
ExtendedHeader eh;
eh.geoBroadcastHeader() = GeoAnycastHeader( // GeoBradcastHeader is identical as GeoAnycastHeader
0,
0,
LongPosVector(
GN__Address(
TypeOfAddress(TypeOfAddress::e__manual), // TODO Use params
StationType(StationType::e__passengerCar), // TODO Use params
33,
p_ll_address
),
0,
_latitude,
_longitude,
int2bit(1, 1), // PAI
0,
0
),
p_geoAreaPosLatitude,
p_geoAreaPosLongitude,
p_distanceA,
p_distanceB,
p_angle,
0
);
_gbc_packet->basicHeader() = fill_basic_header();
eh.geoBroadcastHeader() = GeoAnycastHeader( // GeoBradcastHeader is identical as GeoAnycastHeader
0, 0,
LongPosVector(GN__Address(TypeOfAddress(TypeOfAddress::e__manual), // TODO Use params
StationType(StationType::e__passengerCar), // TODO Use params
33, p_ll_address),
0, _latitude, _longitude, int2bit(1, 1), // PAI
0, 0),
p_geoAreaPosLatitude, p_geoAreaPosLongitude, p_distanceA, p_distanceB, p_angle, 0);
_gbc_packet->basicHeader() = fill_basic_header();
_gbc_packet->gnPacket().packet() = GnNonSecuredPacket(
CommonHeader(
NextHeader(
NextHeader::e__btpA
),
0,
h,
TrafficClass(
SCF(SCF::e__scfDisabled),
ChannelOffload(ChannelOffload::e__choffDisabled),
0
),
int2bit(128, 8), // Mobile stationnary flag set
0,
5,
0
),
OPTIONAL<ExtendedHeader>(eh),
OPTIONAL<GnRawPayload>()
);
CommonHeader(NextHeader(NextHeader::e__btpA), 0, h, TrafficClass(SCF(SCF::e__scfDisabled), ChannelOffload(ChannelOffload::e__choffDisabled), 0),
int2bit(128, 8), // Mobile stationnary flag set
0, 5, 0),
OPTIONAL<ExtendedHeader>(eh), OPTIONAL<GnRawPayload>());
_gbc_packet->gnPacket().packet().payload().set_to_omit();
_gbc_packet->gnPacket().securedMsg().set_to_omit();
//loggers::get_instance().log_msg("geonetworking_layer::fill_gbc_packet: packet value: ", *_gbc_packet);
// loggers::get_instance().log_msg("geonetworking_layer::fill_gbc_packet: packet value: ", *_gbc_packet);
} // End of fill_gbc_packet method
void geonetworking_layer::fill_shb_packet(const OCTETSTRING& p_ll_address)
{
void geonetworking_layer::fill_shb_packet(const OCTETSTRING &p_ll_address) {
_shb_packet = new GeoNetworkingPdu();
HeaderTST h;
h.tsbHdr() = TsbHeaderType(
HeaderType(HeaderType::e__topologicallyScopedBroadcast),
HeaderSubTypeTSB(HeaderSubTypeTSB::e__singleHop)
);
h.tsbHdr() = TsbHeaderType(HeaderType(HeaderType::e__topologicallyScopedBroadcast), HeaderSubTypeTSB(HeaderSubTypeTSB::e__singleHop));
ExtendedHeader eh;
eh.shbHeader() = SHBHeader(
LongPosVector(
GN__Address(
TypeOfAddress(TypeOfAddress::e__manual), // TODO Use params
eh.shbHeader() = SHBHeader(LongPosVector(GN__Address(TypeOfAddress(TypeOfAddress::e__manual), // TODO Use params
StationType(StationType::e__passengerCar), // TODO Use params
33,
p_ll_address
),
0,
_latitude,
_longitude,
int2bit(1, 1), // PAI
0,
0
),
0
);
_shb_packet->basicHeader() = fill_basic_header();
33, p_ll_address),
0, _latitude, _longitude, int2bit(1, 1), // PAI
0, 0),
0);
_shb_packet->basicHeader() = fill_basic_header();
_shb_packet->gnPacket().packet() = GnNonSecuredPacket(
CommonHeader(
NextHeader(
NextHeader::e__btpA
),
0,
h,
TrafficClass(
SCF(SCF::e__scfDisabled),
ChannelOffload(ChannelOffload::e__choffDisabled),
0
),
int2bit(128, 8), // Mobile stationnary flag set
0,
1,
0
),
OPTIONAL<ExtendedHeader>(eh),
OPTIONAL<GnRawPayload>()
);
CommonHeader(NextHeader(NextHeader::e__btpA), 0, h, TrafficClass(SCF(SCF::e__scfDisabled), ChannelOffload(ChannelOffload::e__choffDisabled), 0),
int2bit(128, 8), // Mobile stationnary flag set
0, 1, 0),
OPTIONAL<ExtendedHeader>(eh), OPTIONAL<GnRawPayload>());
_shb_packet->gnPacket().packet().payload().set_to_omit();
_shb_packet->gnPacket().securedMsg().set_to_omit();
//loggers::get_instance().log_msg("geonetworking_layer::fill_shb_packet: packet value: ", *_shb_packet);
// loggers::get_instance().log_msg("geonetworking_layer::fill_shb_packet: packet value: ", *_shb_packet);
} // End of fill_shb_packet method
void geonetworking_layer::fill_tsb_packet(const OCTETSTRING& p_ll_address, const int p_hop_number, const int p_max_hop_limit)
{
void geonetworking_layer::fill_tsb_packet(const OCTETSTRING &p_ll_address, const int p_hop_number, const int p_max_hop_limit) {
_tsb_packet = new GeoNetworkingPdu();
HeaderTST h;
h.tsbHdr() = TsbHeaderType(
HeaderType(HeaderType::e__topologicallyScopedBroadcast),
HeaderSubTypeTSB(HeaderSubTypeTSB::e__multiHop)
);
h.tsbHdr() = TsbHeaderType(HeaderType(HeaderType::e__topologicallyScopedBroadcast), HeaderSubTypeTSB(HeaderSubTypeTSB::e__multiHop));
ExtendedHeader eh;
eh.tsbHeader() = TSBHeader(
0,
0,
LongPosVector(
GN__Address(
TypeOfAddress(TypeOfAddress::e__manual), // TODO Use params
eh.tsbHeader() = TSBHeader(0, 0,
LongPosVector(GN__Address(TypeOfAddress(TypeOfAddress::e__manual), // TODO Use params
StationType(StationType::e__passengerCar), // TODO Use params
33,
p_ll_address
),
0,
_latitude,
_longitude,
int2bit(1, 1), // PAI
0,
0
)
);
_tsb_packet->basicHeader() = fill_basic_header();
33, p_ll_address),
0, _latitude, _longitude, int2bit(1, 1), // PAI
0, 0));
_tsb_packet->basicHeader() = fill_basic_header();
_tsb_packet->gnPacket().packet() = GnNonSecuredPacket(
CommonHeader(
NextHeader(
NextHeader::e__btpA
),
0,
h,
TrafficClass(
SCF(SCF::e__scfDisabled),
ChannelOffload(ChannelOffload::e__choffDisabled),
0
),
int2bit(128, 8), // Mobile stationnary flag set
0,
p_max_hop_limit,
0
),
OPTIONAL<ExtendedHeader>(eh),
OPTIONAL<GnRawPayload>()
);
CommonHeader(NextHeader(NextHeader::e__btpA), 0, h, TrafficClass(SCF(SCF::e__scfDisabled), ChannelOffload(ChannelOffload::e__choffDisabled), 0),
int2bit(128, 8), // Mobile stationnary flag set
0, p_max_hop_limit, 0),
OPTIONAL<ExtendedHeader>(eh), OPTIONAL<GnRawPayload>());
_tsb_packet->gnPacket().packet().payload().set_to_omit();
_tsb_packet->gnPacket().securedMsg().set_to_omit();
//loggers::get_instance().log_msg("geonetworking_layer::fill_tsb_packet: packet value: ", *_tsb_packet);
// loggers::get_instance().log_msg("geonetworking_layer::fill_tsb_packet: packet value: ", *_tsb_packet);
} // End of fill_tsb_packet method
void geonetworking_layer::fill_uni_packet(const OCTETSTRING& p_ll_address, const int p_hop_number, const int p_max_hop_limit)
{
void geonetworking_layer::fill_uni_packet(const OCTETSTRING &p_ll_address, const int p_hop_number, const int p_max_hop_limit) {
_uni_packet = new GeoNetworkingPdu();
HeaderTST h;
h.geoUnicastHdr() = GeoUnicastHeaderType(
HeaderType(HeaderType::e__geoUnicast),
0
);
h.geoUnicastHdr() = GeoUnicastHeaderType(HeaderType(HeaderType::e__geoUnicast), 0);
ExtendedHeader eh;
eh.geoUnicastHeader() = GeoUnicastHeader(
0,
0,
LongPosVector(
GN__Address(
TypeOfAddress(TypeOfAddress::e__manual), // TODO Use params
eh.geoUnicastHeader() = GeoUnicastHeader(0, 0,
LongPosVector(GN__Address(TypeOfAddress(TypeOfAddress::e__manual), // TODO Use params
StationType(StationType::e__passengerCar), // TODO Use params
33,
p_ll_address
),
0,
_latitude,
_longitude,
int2bit(1, 1), // PAI
0,
0
),
ShortPosVector(
GN__Address(
TypeOfAddress(TypeOfAddress::e__manual), // TODO Use params
33, p_ll_address),
0, _latitude, _longitude, int2bit(1, 1), // PAI
0, 0),
ShortPosVector(GN__Address(TypeOfAddress(TypeOfAddress::e__manual), // TODO Use params
StationType(StationType::e__passengerCar), // TODO Use params
33,
p_ll_address
),
0,
_latitude + 100,
_longitude + 100
)
);
_uni_packet->basicHeader() = fill_basic_header();
33, p_ll_address),
0, _latitude + 100, _longitude + 100));
_uni_packet->basicHeader() = fill_basic_header();
_uni_packet->gnPacket().packet() = GnNonSecuredPacket(
CommonHeader(
NextHeader(
NextHeader::e__btpA
),
0,
h,
TrafficClass(
SCF(SCF::e__scfDisabled),
ChannelOffload(ChannelOffload::e__choffDisabled),
0
),
int2bit(128, 8), // Mobile stationnary flag set
0,
p_max_hop_limit,
0
),
OPTIONAL<ExtendedHeader>(eh),
OPTIONAL<GnRawPayload>()
);
CommonHeader(NextHeader(NextHeader::e__btpA), 0, h, TrafficClass(SCF(SCF::e__scfDisabled), ChannelOffload(ChannelOffload::e__choffDisabled), 0),
int2bit(128, 8), // Mobile stationnary flag set
0, p_max_hop_limit, 0),
OPTIONAL<ExtendedHeader>(eh), OPTIONAL<GnRawPayload>());
_uni_packet->gnPacket().packet().payload().set_to_omit();
_uni_packet->gnPacket().securedMsg().set_to_omit();
//loggers::get_instance().log_msg("geonetworking_layer::fill_uni_packet: packet value: ", *_uni_packet);
// loggers::get_instance().log_msg("geonetworking_layer::fill_uni_packet: packet value: ", *_uni_packet);
} // End of fill_uni_packet method
void geonetworking_layer::fill_ls_reply(const OCTETSTRING& p_ll_address)
{
void geonetworking_layer::fill_ls_reply(const OCTETSTRING &p_ll_address) {
_ls_reply = new GeoNetworkingPdu();
HeaderTST h;
h.lsHdr() = LsHeaderType(
HeaderType(HeaderType::e__locationService),
HeaderSubTypeLs(HeaderSubTypeLs::e__lsReply)
);
h.lsHdr() = LsHeaderType(HeaderType(HeaderType::e__locationService), HeaderSubTypeLs(HeaderSubTypeLs::e__lsReply));
ExtendedHeader eh;
eh.lsReplyHeader() = LSReplyHeader(
0,
0,
LongPosVector(
GN__Address(
TypeOfAddress(TypeOfAddress::e__manual), // TODO Use params
eh.lsReplyHeader() = LSReplyHeader(0, 0,
LongPosVector(GN__Address(TypeOfAddress(TypeOfAddress::e__manual), // TODO Use params
StationType(StationType::e__passengerCar), // TODO Use params
33,
p_ll_address
),
0,
_latitude,
_longitude,
int2bit(1, 1), // PAI
0,
0
),
ShortPosVector(
GN__Address(
TypeOfAddress(TypeOfAddress::e__manual), // TODO Use params
33, p_ll_address),
0, _latitude, _longitude, int2bit(1, 1), // PAI
0, 0),
ShortPosVector(GN__Address(TypeOfAddress(TypeOfAddress::e__manual), // TODO Use params
StationType(StationType::e__passengerCar), // TODO Use params
33,
p_ll_address
),
0,
_latitude,
_longitude
)
);
_ls_reply->basicHeader() = fill_basic_header();
_ls_reply->gnPacket().packet() = GnNonSecuredPacket(
CommonHeader(
NextHeader(
NextHeader::e__any
),
0,
h,
TrafficClass(
SCF(SCF::e__scfDisabled),
ChannelOffload(ChannelOffload::e__choffDisabled),
0
),
33, p_ll_address),
0, _latitude, _longitude));
_ls_reply->basicHeader() = fill_basic_header();
_ls_reply->gnPacket().packet() = GnNonSecuredPacket(CommonHeader(NextHeader(NextHeader::e__any), 0, h,
TrafficClass(SCF(SCF::e__scfDisabled), ChannelOffload(ChannelOffload::e__choffDisabled), 0),
int2bit(128, 8), // Mobile stationnary flag set
0,
5,
0
),
OPTIONAL<ExtendedHeader>(eh),
OPTIONAL<GnRawPayload>()
);
0, 5, 0),
OPTIONAL<ExtendedHeader>(eh), OPTIONAL<GnRawPayload>());
_ls_reply->gnPacket().packet().payload().set_to_omit();
_ls_reply->gnPacket().securedMsg().set_to_omit();
//loggers::get_instance().log_msg("geonetworking_layer::fill_ls_reply: packet value: ", *_ls_reply);
// loggers::get_instance().log_msg("geonetworking_layer::fill_ls_reply: packet value: ", *_ls_reply);
} // End of fill_ls_reply method
void geonetworking_layer::timer_irq_sigalrm_handler(int p_signal, siginfo_t *p_signal_info, void *p_uc) {
//loggers::get_instance().log(">>> geonetworking_layer::timer_irq_sigalrm_handler: Caught signal %d", p_signal);
// loggers::get_instance().log(">>> geonetworking_layer::timer_irq_sigalrm_handler: Caught signal %d", p_signal);
static_cast<geonetworking_layer *>(p_signal_info->si_value.sival_ptr)->send_beacon();
} // End of method timer_irq_sigalrm_handler
int geonetworking_layer::build_geonetworking_pdu(OCTETSTRING& data, params& params) {
int geonetworking_layer::build_geonetworking_pdu(OCTETSTRING &data, params &params) {
loggers::get_instance().log(">>> geonetworking_layer::build_geonetworking_pdu");
//params.log();
std::string next_header;
// params.log();
std::string next_header;
params::const_iterator it = params.find(params::next_header);
if (it != params.cend()) {
next_header = it->second.c_str();
......@@ -959,10 +751,10 @@ int geonetworking_layer::build_geonetworking_pdu(OCTETSTRING& data, params& para
header_sub_type = it->second.c_str();
}
loggers::get_instance().log("geonetworking_layer::build_geonetworking_pdu: %s, %s, %s", next_header.c_str(), header_type.c_str(), header_sub_type.c_str());
if (header_type.compare("tsb") == 0) {
if (header_sub_type.compare("sh") == 0) { // Use SHB
ExtendedHeader* eh = static_cast<ExtendedHeader *>(_shb_packet->gnPacket().packet().extendedHeader().get_opt_value());
ExtendedHeader *eh = static_cast<ExtendedHeader *>(_shb_packet->gnPacket().packet().extendedHeader().get_opt_value());
if (eh == nullptr) {
loggers::get_instance().error("geonetworking_layer::build_geonetworking_pdu: Wrong cast");
return -1;
......@@ -976,17 +768,17 @@ int geonetworking_layer::build_geonetworking_pdu(OCTETSTRING& data, params& para
}
// Update payload
_shb_packet->gnPacket().packet().commonHeader().plLength() = data.lengthof();
_shb_packet->gnPacket().packet().payload() = OPTIONAL<OCTETSTRING>(data);
_shb_packet->gnPacket().packet().payload() = OPTIONAL<OCTETSTRING>(data);
// Update timestamp
eh->shbHeader().srcPosVector().timestamp__().set_long_long_val(static_cast<unsigned int>(base_time::get_instance().get_its_current_time_mod_ms()));
loggers::get_instance().log_msg("geonetworking_layer::build_geonetworking_pdu: shb: ", *_shb_packet);
// Encode GeoNetworking PDU
OCTETSTRING os;
_codec.encode(*_shb_packet, os);
data = os;
} else { // Use TSB
ExtendedHeader* eh = static_cast<ExtendedHeader *>(_tsb_packet->gnPacket().packet().extendedHeader().get_opt_value());
ExtendedHeader *eh = static_cast<ExtendedHeader *>(_tsb_packet->gnPacket().packet().extendedHeader().get_opt_value());
if (eh == nullptr) {
loggers::get_instance().error("geonetworking_layer::build_geonetworking_pdu: Wrong cast");
return -1;
......@@ -1002,10 +794,10 @@ int geonetworking_layer::build_geonetworking_pdu(OCTETSTRING& data, params& para
}
// Update payload
_tsb_packet->gnPacket().packet().commonHeader().plLength() = data.lengthof();
_tsb_packet->gnPacket().packet().payload() = OPTIONAL<OCTETSTRING>(data);
_tsb_packet->gnPacket().packet().payload() = OPTIONAL<OCTETSTRING>(data);
// Update timestamp
eh->tsbHeader().srcPosVector().timestamp__().set_long_long_val(static_cast<unsigned int>(base_time::get_instance().get_its_current_time_mod_ms()));
loggers::get_instance().log_msg("geonetworking_layer::build_geonetworking_pdu: tsb: ", *_tsb_packet);
// Encode GeoNetworking PDU
OCTETSTRING os;
......@@ -1013,7 +805,7 @@ int geonetworking_layer::build_geonetworking_pdu(OCTETSTRING& data, params& para
data = os;
}
} else if (header_type.compare("uni") == 0) {
ExtendedHeader* eh = static_cast<ExtendedHeader *>(_uni_packet->gnPacket().packet().extendedHeader().get_opt_value());
ExtendedHeader *eh = static_cast<ExtendedHeader *>(_uni_packet->gnPacket().packet().extendedHeader().get_opt_value());
if (eh == nullptr) {
loggers::get_instance().error("geonetworking_layer::build_geonetworking_pdu: Wrong cast");
return -1;
......@@ -1029,10 +821,10 @@ int geonetworking_layer::build_geonetworking_pdu(OCTETSTRING& data, params& para
eh->geoUnicastHeader().seqNumber() = _sequence_number++;
// Update payload
_uni_packet->gnPacket().packet().commonHeader().plLength() = data.lengthof();
_uni_packet->gnPacket().packet().payload() = OPTIONAL<OCTETSTRING>(data);
_uni_packet->gnPacket().packet().payload() = OPTIONAL<OCTETSTRING>(data);
// Update timestamp
eh->geoUnicastHeader().srcPosVector().timestamp__().set_long_long_val(static_cast<unsigned int>(base_time::get_instance().get_its_current_time_mod_ms()));
loggers::get_instance().log_msg("geonetworking_layer::build_geonetworking_pdu: uni: ", *_uni_packet);
// Encode GeoNetworking PDU
......@@ -1041,7 +833,7 @@ int geonetworking_layer::build_geonetworking_pdu(OCTETSTRING& data, params& para
data = os;
} else { // TODO To be continued
// Default: Use GBC
ExtendedHeader* eh = static_cast<ExtendedHeader *>(_gbc_packet->gnPacket().packet().extendedHeader().get_opt_value());
ExtendedHeader *eh = static_cast<ExtendedHeader *>(_gbc_packet->gnPacket().packet().extendedHeader().get_opt_value());
if (eh == nullptr) {
loggers::get_instance().error("geonetworking_layer::build_geonetworking_pdu: Wrong cast");
return -1;
......@@ -1057,10 +849,10 @@ int geonetworking_layer::build_geonetworking_pdu(OCTETSTRING& data, params& para
eh->geoBroadcastHeader().seqNumber() = _sequence_number++;
// Update payload
_gbc_packet->gnPacket().packet().commonHeader().plLength() = data.lengthof();
_gbc_packet->gnPacket().packet().payload() = OPTIONAL<OCTETSTRING>(data);
_gbc_packet->gnPacket().packet().payload() = OPTIONAL<OCTETSTRING>(data);
// Update timestamp
eh->geoBroadcastHeader().srcPosVector().timestamp__().set_long_long_val(static_cast<unsigned int>(base_time::get_instance().get_its_current_time_mod_ms()));
loggers::get_instance().log_msg("geonetworking_layer::build_geonetworking_pdu: gbc: ", *_gbc_packet);
// Encode GeoNetworking PDU
......@@ -1068,14 +860,14 @@ int geonetworking_layer::build_geonetworking_pdu(OCTETSTRING& data, params& para
_codec.encode(*_gbc_packet, os);
data = os;
}
return 0;
}
int geonetworking_layer::build_secured_pdu(OCTETSTRING& data, params& params) {
int geonetworking_layer::build_secured_pdu(OCTETSTRING &data, params &params) {
loggers::get_instance().log_msg(">>> geonetworking_layer::build_secured_pdu: ", data);
//params.log();
// params.log();
LibItsGeoNetworking__TypesAndValues::BasicHeader basic_header;
decode_basic_header(data, basic_header);
if (basic_header.nextHeader() == BasicNextHeader::e__securedPacket) { // Already secured (ATS Security test suite/f_sendSecuredGn/Cam/Denm TTCN-3 functions
......@@ -1084,10 +876,10 @@ int geonetworking_layer::build_secured_pdu(OCTETSTRING& data, params& params) {
return 0;
}
// Update security mode
unsigned int basic_header_len = 4;// FIXME How to retrive the BasicHeader length basic_header.get_descriptor()->raw->fieldlength / 8;
unsigned int basic_header_len = 4; // FIXME How to retrive the BasicHeader length basic_header.get_descriptor()->raw->fieldlength / 8;
loggers::get_instance().log("geonetworking_layer::build_secured_pdu: basic_header_len = %d", basic_header_len);
basic_header.nextHeader() = BasicNextHeader::e__securedPacket;
OCTETSTRING unsecured_gn_payload = OCTETSTRING(data.lengthof() - basic_header_len, static_cast<const unsigned char*>(data) + basic_header_len);
basic_header.nextHeader() = BasicNextHeader::e__securedPacket;
OCTETSTRING unsecured_gn_payload = OCTETSTRING(data.lengthof() - basic_header_len, static_cast<const unsigned char *>(data) + basic_header_len);
OCTETSTRING secured_gn_payload;
if (security_services::get_instance().secure_gn_payload(unsecured_gn_payload, secured_gn_payload, params) != 0) {
loggers::get_instance().warning("geonetworking_layer::build_secured_pdu: failed to build secured pdu");
......@@ -1095,33 +887,32 @@ int geonetworking_layer::build_secured_pdu(OCTETSTRING& data, params& params) {
}
// Encode the basic header
//loggers::get_instance().log_msg("geonetworking_layer::build_secured_pdu: New basic_header = ", basic_header);
// loggers::get_instance().log_msg("geonetworking_layer::build_secured_pdu: New basic_header = ", basic_header);
RAW_enc_tr_pos rp;
rp.level=0;
rp.pos=NULL;
rp.level = 0;
rp.pos = NULL;
RAW_enc_tree enc_tree(FALSE, NULL, &rp, 1, basic_header.get_descriptor()->raw);
basic_header.RAW_encode(*basic_header.get_descriptor(), enc_tree);
TTCN_Buffer encoding_buffer;
enc_tree.put_to_buf(encoding_buffer);
// Copy result
data =
OCTETSTRING(encoding_buffer.get_len(), encoding_buffer.get_data()) +
secured_gn_payload;
data = OCTETSTRING(encoding_buffer.get_len(), encoding_buffer.get_data()) + secured_gn_payload;
loggers::get_instance().log_msg("geonetworking_layer::build_secured_pdu: Secured pdu = ", data);
return 0;
}
int geonetworking_layer::decode_basic_header(const OCTETSTRING& p_data, LibItsGeoNetworking__TypesAndValues::BasicHeader& p_basic_header) {
//loggers::get_instance().log_msg(">>> geonetworking_layer::decode_basic_header: ", p_data);
int geonetworking_layer::decode_basic_header(const OCTETSTRING &p_data, LibItsGeoNetworking__TypesAndValues::BasicHeader &p_basic_header) {
// loggers::get_instance().log_msg(">>> geonetworking_layer::decode_basic_header: ", p_data);
// Update security mode
OCTETSTRING bh = OCTETSTRING(4, static_cast<const unsigned char*>(p_data)); // Extract the basic header as specified in ETSI EN 302 636-4-1 V1.3.1 (2017-08) Clause 9.6
//loggers::get_instance().log_msg("geonetworking_layer::decode_basic_header: bh: ", bh);
OCTETSTRING bh =
OCTETSTRING(4, static_cast<const unsigned char *>(p_data)); // Extract the basic header as specified in ETSI EN 302 636-4-1 V1.3.1 (2017-08) Clause 9.6
// loggers::get_instance().log_msg("geonetworking_layer::decode_basic_header: bh: ", bh);
TTCN_Buffer decoding_buffer(bh);
p_basic_header.RAW_decode(*p_basic_header.get_descriptor(), decoding_buffer, decoding_buffer.get_len() * 8, raw_order_t::ORDER_MSB);
//loggers::get_instance().log_msg("geonetworking_layer::decode_basic_header: ", p_basic_header);
// loggers::get_instance().log_msg("geonetworking_layer::decode_basic_header: ", p_basic_header);
return 0;
}
......