Compare Revisions

The credentials to download the source code are:
 Username: svnusers
 Password: svnusers

Ignore whitespace Rev 3314 → Rev 3315

/branches/STF525/ccsrc/Ports/LibIts_ports/RSUsSimulator_ports/ConfigRsuSimulatorLayer.cc
87,8 → 87,10
unsigned char id = *(static_cast<const unsigned char*>(data));
if (id == 0x00) { // Receive an UtxxInitialise
process_utinitialize_data(data, params);
} else if (id == 0x31) { // Receive an UtCamChangeSpeed
} else if (id == 0x31/*uppertester_cam_codec::c_utCamChangeSpeed*/) {
process_ut_cam_changespeed_data(data, params);
} else if (id == 0x30/*uppertester_cam_codec::c_utCamChangeCurvature*/) {
process_ut_cam_changecurvature_data(data, params);
} else if ((id >= 0x50) && (id <= 0x54)) { // Receive an UtGnTrigger
process_ut_geonetworking_trigger(data, params);
} else {
152,6 → 154,29
return 0;
}
 
int ConfigRsuSimulatorLayer::process_ut_cam_changecurvature_data(const OCTETSTRING& data, params& params) {
loggers::get_instance().log(">>> ConfigRsuSimulatorLayer::process_ut_cam_changecurvature_data");
 
params::const_iterator it = _params.find("ut");
if (it == _params.cend()) {
loggers::get_instance().warning("ConfigRsuSimulatorLayer::process_ut_cam_changecurvature_data: CF layer's ut parameter is missing");
return -1;
}
 
if (_params[std::string("ut")].compare("cam") == 0) {
OCTETSTRING speed(data.lengthof() - 1, 1 + static_cast<const unsigned char*>(data));
LibItsCam__TypesAndValues::UtCamTrigger p;
p.changeCurvature() = oct2int(speed);
// Pass it to the ports if any
to_all_upper_ports(p, params);
} else {
loggers::get_instance().warning("ConfigRsuSimulatorLayer::process_ut_cam_changecurvature_data: Unsupported protocol");
return -1;
}
 
return 0;
}
 
int ConfigRsuSimulatorLayer::process_ut_geonetworking_trigger(const OCTETSTRING& data, params& params) {
loggers::get_instance().log(">>> ConfigRsuSimulatorLayer::process_ut_geonetworking_trigger");
 
/branches/STF525/ccsrc/Ports/LibIts_ports/RSUsSimulator_ports/ConfigRsuSimulatorLayer.hh
42,6 → 42,7
private:
int process_utinitialize_data(const OCTETSTRING& data, params& params);
int process_ut_cam_changespeed_data(const OCTETSTRING& data, params& params);
int process_ut_cam_changecurvature_data(const OCTETSTRING& data, params& params);
int process_ut_geonetworking_trigger(const OCTETSTRING& data, params& params);
 
}; // End of class ConfigRsuSimulatorLayer
/branches/STF525/ccsrc/Protocols/Pcap/pcap_layer.cc
280,7 → 280,7
float duration;
loggers::get_instance().set_start_time(_time_key);
this->receive_data(os, params); // TODO Check execution time for decoding operation
loggers::get_instance().set_stop_time(_time_key, duration);
loggers::get_instance().set_stop_time(_time_key, duration);
}
} // else, skip the packet
// Specific to offline mode
/branches/STF525/ccsrc/Protocols/UDP/udp_layer.cc
1,9 → 1,16
#include "udp_layer_factory.hh"
#include <netdb.h>
#include <unistd.h>
#include <chrono>
 
#include <Port.hh>
 
#include "loggers.hh"
 
udp_layer::udp_layer(const std::string & p_type, const std::string & param) : layer(p_type), _params() {
#include "udp_layer_factory.hh"
 
udp_layer::udp_layer(const std::string & p_type, const std::string & param) : layer(p_type), PORT(p_type.c_str()), _params(), _saddr{0}, _daddr{0}, _fd(-1), _time_key("udp_layer::Handle_Fd_Event_Readable") {
loggers::get_instance().log(">>> udp_layer::udp_layer: %s, %s", to_string().c_str(), param.c_str());
// Setup parameters
params::convert(_params, param);
params::const_iterator it = _params.find("src_ip");
23,108 → 30,110
_params.insert(std::pair<std::string, std::string>(std::string("dst_port"), "12346"));
}
 
//_params.log();
// Initialize the socket
_saddr.sin_family = AF_INET;
_saddr.sin_addr.s_addr = htonl(INADDR_ANY);
_saddr.sin_port = htons(std::atoi(_params["src_port"].c_str()));
// Create socket
_fd = ::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (_fd == -1) {
loggers::get_instance().error("udp_layer::udp_layer: Failed to create socket");
}
loggers::get_instance().log("udp_layer::udp_layer: socket id: %d", _fd);
if (::setsockopt(_fd, SOL_SOCKET, SO_REUSEADDR, nullptr, 0) < 0) {
loggers::get_instance().warning("udp_layer::udp_layer: Failed to set SO_REUSEADDR");
}
// Bind it
if(::bind(_fd, (struct sockaddr *)&_saddr, sizeof(_saddr)) < 0) {
close();
loggers::get_instance().error("udp_layer::udp_layer: Failed to bind socket");
}
// Pass the device file handler to the polling procedure
Handler_Add_Fd_Read(_fd);
_daddr.sin_family = AF_INET;
_daddr.sin_addr.s_addr = htonl(get_host_id(_params["dsp_ip"]));
_daddr.sin_port = htons(std::atoi(_params["dst_port"].c_str()));
}
 
udp_layer::~udp_layer() {
loggers::get_instance().log(">>> udp_layer::~udp_layer");
 
close();
}
 
void udp_layer::close() {
loggers::get_instance().log(">>> udp_layer::close: %d", _fd);
 
if (_fd != -1) {
::close(_fd);
_fd = -1;
}
}
 
void udp_layer::send_data(OCTETSTRING& data, params& params) {
loggers::get_instance().log_msg(">>> udp_layer::send_data: ", data);
// Create IP/UDP packet
unsigned int len = sizeof(struct iphdr) + sizeof(struct udphdr) + data.lengthof();
unsigned char *buffer = new unsigned char[len];
// Set ip header
_iphdr = (struct iphdr *)buffer;
_daddr.sin_family = AF_INET;
_saddr.sin_family = AF_INET;
params::const_iterator it = _params.find("dst_port");
_daddr.sin_port = htons(std::strtoul(it->second.c_str(), NULL, 10));
it = _params.find("src_port");
_saddr.sin_port = htons(std::strtoul(it->second.c_str(), NULL, 10));
it = _params.find("dst_ip");
inet_pton(AF_INET, it->second.c_str(), (struct in_addr *)&_daddr.sin_addr.s_addr);
it = _params.find("src_ip");
inet_pton(AF_INET, it->second.c_str(), (struct in_addr *)&_saddr.sin_addr.s_addr);
_iphdr->ihl = 5;
_iphdr->version = 4;
_iphdr->tos = IPTOS_LOWDELAY;
_iphdr->id = 0;
_iphdr->frag_off = htons(0x4000); /* Don't fragment */
_iphdr->ttl = 64;
_iphdr->tot_len = htons(sizeof(struct iphdr) + sizeof(struct udphdr) + data.lengthof());
_iphdr->protocol = IPPROTO_UDP;
#if defined (LINUX)
_iphdr->saddr = _saddr.sin_addr.s_addr;
_iphdr->daddr = _daddr.sin_addr.s_addr;
#else
_iphdr->saddr = _saddr.sin_addr;
_iphdr->daddr = _daddr.sin_addr;
#endif
_iphdr->check = 0;
_iphdr->check = inet_check_sum((const void *)_iphdr, sizeof(struct iphdr));
// Set udp header
_udphdr = (struct udphdr *)(buffer + sizeof(struct iphdr));
_udphdr->source = _saddr.sin_port;
_udphdr->dest = _daddr.sin_port;
_udphdr->len = htons(sizeof(struct udphdr) + data.lengthof());
_udphdr->check = 0;
// Set payload
unsigned char *payload = buffer + sizeof(struct iphdr) + sizeof(struct udphdr);
memcpy(payload, static_cast<const unsigned char *>(data), data.lengthof());
// Calculate UDP checksum
_udphdr->check = inet_check_sum(
(const void *)_udphdr,
sizeof(struct udphdr),
inet_check_sum(
static_cast<const unsigned char*>(data),
data.lengthof(),
inet_check_sum(
(const unsigned char*)(&(_iphdr->saddr)),
2 * sizeof(_iphdr->saddr),
IPPROTO_UDP + static_cast<unsigned int>(ntohs(_udphdr->len))
)
)
);
// Send data lower layers
OCTETSTRING udp(len, buffer);
send_to_all_layers(udp, params);
// Free buffer
delete [] buffer;
int result = ::sendto(_fd, (const char*)static_cast<const unsigned char*>(data), data.lengthof(), 0, (struct sockaddr*)&_daddr, sizeof(_daddr));
loggers::get_instance().log("udp_layer::send_data: #bytes sent: %d", result);
}
 
void udp_layer::receive_data(OCTETSTRING& data, params& params) {
loggers::get_instance().log_msg(">>> udp_layer::receive_data: ", data);
 
// Decode UDP packet
const unsigned char* buffer = static_cast<const unsigned char *>(data);
_iphdr = (struct iphdr*)buffer;
_udphdr = (struct udphdr*)(buffer + sizeof(struct iphdr));
loggers::get_instance().log("udp_layer::receive_data: src_port = %d, payload length = %d", ntohs(_udphdr->source), ntohs(_udphdr->len));
// TODO To be refined
data = OCTETSTRING(ntohs(_udphdr->len) - sizeof(struct udphdr), (unsigned char*)(buffer + sizeof(struct iphdr) + sizeof(struct udphdr)));
//loggers::get_instance().log_msg("udp_layer::receive_data: message payload", data);
receive_to_all_layers(data, params);
}
 
unsigned short udp_layer::inet_check_sum(const void *buf, size_t len, const unsigned short p_initial_sum) {
unsigned long sum = p_initial_sum;
unsigned int i;
void udp_layer::Handle_Fd_Event_Readable(int fd) {
loggers::get_instance().log(">>> udp_layer::Handle_Fd_Event_Readable: %d", fd);
 
unsigned char buffer[2048] = {0};
struct sockaddr_in from = {0};
socklen_t len = 0; // Length of sender's address
params params;
int result = ::recvfrom(_fd, buffer, 1024, 0, (struct sockaddr *)&from, &len); // FIXME Add support of EAGAIN
loggers::get_instance().log("udp_layer::receive_data: src_port = %s:%d, payload length = %d", ::inet_ntoa(from.sin_addr), ntohs(from.sin_port), result);
params.insert(std::pair<std::string, std::string>(std::string("timestamp"), std::to_string(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count())));
if (result < 0) {
loggers::get_instance().warning("udp_layer::receive_data: Failed to read data, discard them");
return;
}
// Checksum all the pairs of bytes first...
for (i = 0; i < (len & ~1U); i += 2) {
sum += (u_int16_t)ntohs(*((u_int16_t *)((unsigned char*)buf + i)));
if (sum > 0xFFFF)
sum -= 0xFFFF;
} // End of 'for' statement
// If there's a single byte left over, checksum it, too
if (i < len) {
sum += *((unsigned char*)buf + i) << 8;
if (sum > 0xFFFF) {
sum -= 0xFFFF;
float duration;
loggers::get_instance().set_start_time(_time_key);
OCTETSTRING os(result, buffer);
receive_data(os, params); // TODO Check execution time for decoding operation
loggers::get_instance().set_stop_time(_time_key, duration);
}
 
unsigned long udp_layer::get_host_id(const std::string& p_host_name) {
loggers::get_instance().log(">>> udp_layer::get_host_id");
 
if (p_host_name.empty()) {
return INADDR_ANY;
}
unsigned long ip_addr = 0;
if(p_host_name.compare("255.255.255.255") == 0) {
ip_addr = 0xffffffff;
} else {
in_addr_t addr = ::inet_addr(p_host_name.c_str());
if (addr != (in_addr_t) - 1) { // host name in XX:XX:XX:XX form
ip_addr = addr;
} else { // host name in domain.com form
struct hostent* hptr;
if ((hptr = ::gethostbyname(p_host_name.c_str())) == 0) {
close();
loggers::get_instance().error("udp_layer::get_host_id: Invalid host name: %s", p_host_name.c_str());
}
ip_addr = *((unsigned long*)hptr->h_addr_list[0]);
}
}
return htons((~sum & 0xffff));
loggers::get_instance().log("udp_layer::get_host_id: Host name: %s, Host address: %u", p_host_name.c_str(), ip_addr);
return ip_addr;
}
 
udp_layer_factory udp_layer_factory::_f;
/branches/STF525/ccsrc/Protocols/UDP/udp_layer.hh
10,65 → 10,27
*/
#pragma once
 
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#if !defined(LINUX)
#include <netdb.h>
struct iphdr {
#if __BYTE_ORDER == __LITTLE_ENDIAN
u_int8_t ihl:4,
version:4;
#elif __BYTE_ORDER == __BIG_ENDIAN
u_int8_t version:4,
ihl:4;
#else
#error "Please fix <asm/byteorder.h>"
#endif
u_int8_t tos;
u_int16_t tot_len;
u_int16_t id;
u_int16_t frag_off;
u_int8_t ttl;
u_int8_t protocol;
u_int16_t check;
struct in_addr saddr;
struct in_addr daddr;
//The options start here.
};
struct udphdr {
u_int16_t source;
u_int16_t dest;
u_int16_t len;
u_int16_t check;
};
#else // LINUX
#include <linux/ip.h>
#include <linux/udp.h>
#endif // LINUX
 
#include "t_layer.hh"
#include "params.hh"
 
class PORT; //! Forward declaration of TITAN class
 
/*!
* \class udp_layer
* \brief This class provides description of ITS UDP/IP protocol layer
*/
class udp_layer : public layer {
class udp_layer : public layer, public PORT {
params _params; //! Layer parameters
struct iphdr* _iphdr; //! IP layer description
struct udphdr* _udphdr; //! UDP layer description
struct sockaddr_in _saddr; //! Source socket address description
struct sockaddr_in _daddr; //! Destination socket address description
int _fd; // Socket file descriptor
std::string _time_key; //! \todo
 
/*!
* \fn unsigned short inet_check_sum(const void *buf, size_t hdr_len, const unsigned short p_initial_sum = 0);
* \brief Compute the UDP checksum
* \param[in] p_buffer The data to be sent
* \param[in] p_header_length The UDP header length
* \param [in] p_initial_sum The initial checksum value. Default: 0
* \return The checksum value
*/
unsigned short inet_check_sum(const void *p_buffer, size_t p_header_length, const unsigned short p_initial_sum = 0);
 
public: //! \publicsection
/*!
* \brief Specialised constructor
80,7 → 42,7
/*!
* \brief Default destructor
*/
virtual ~udp_layer() {}
virtual ~udp_layer();
 
/*!
* \virtual
98,5 → 60,11
* \param[in] p_params Some lower layers parameters values when data was received
*/
virtual void receive_data(OCTETSTRING& data, params& info);
void Handle_Fd_Event_Readable(int fd);
 
private:
unsigned long get_host_id(const std::string& p_host_name);
void close();
}; // End of class udp_layer
 
/branches/STF525/ccsrc/Protocols/UpperTester/uppertester_cam_codec.hh
30,6 → 30,7
Record_Type,
Record_Type>
{
public:
const unsigned char c_utCamInitialize = 0x00;
const unsigned char c_utCamInitializeResult = 0x01;
const unsigned char c_utCamChangePosition = 0x02;
50,6 → 51,7
const unsigned char c_utCamTriggerResult = 0x21;
const unsigned char c_utCamEventInd = 0x23;
 
private:
int encode_ (const Base_Type& type, const TTCN_Typedescriptor_t& field_descriptor, TTCN_Buffer& encoding_buffer);
 
public:
/branches/STF525/ccsrc/Protocols/UpperTester/uppertester_geonetworking_codec.cc
109,12 → 109,14
 
int uppertester_geonetworking_codec::decode (const OCTETSTRING& data, Record_Type& msg, params* params)
{
loggers::get_instance().log_msg(">>> uppertester_geonetworking_codec::decode (1): ", data);
TTCN_EncDec::clear_error();
TTCN_Buffer decoding_buffer(data);
_params = params;
loggers::get_instance().log_to_hexa(">>> uppertester_geonetworking_codec::decode: decoding_buffer=", decoding_buffer);
//decode_(msg, *msg.get_descriptor(), decoding_buffer);
loggers::get_instance().log_to_hexa("uppertester_geonetworking_codec::decode: decoding_buffer=", decoding_buffer);
// decode_(msg, *msg.get_descriptor(), decoding_buffer);
loggers::get_instance().log_msg("<<< uppertester_geonetworking_codec::decode: ", (const Record_Type&)msg);
return 0;
121,6 → 123,7
}
 
std::unique_ptr<Base_Type> uppertester_geonetworking_codec::decode (const OCTETSTRING& data, params* params) {
loggers::get_instance().log_msg(">>> uppertester_geonetworking_codec::decode (2): ", data);
 
std::unique_ptr<Base_Type> result;
144,7 → 147,7
 
int uppertester_geonetworking_codec::decode (const OCTETSTRING& data, LibItsGeoNetworking__TypesAndValues::UtGnResults& msg, params* params)
{
loggers::get_instance().log_to_hexa(">>> uppertester_geonetworking_codec::decode: decoding_buffer=", data);
loggers::get_instance().log_msg(">>> uppertester_geonetworking_codec::decode (3): ", data);
 
const unsigned char* ptr = static_cast<const unsigned char*>(data);
if (*ptr == uppertester_geonetworking_codec::c_utGnInitializeResult) {
163,7 → 166,7
 
int uppertester_geonetworking_codec::decode (const OCTETSTRING& data, LibItsGeoNetworking__TypesAndValues::UtGnEventInd& msg, params* params)
{
loggers::get_instance().log_to_hexa(">>> uppertester_geonetworking_codec::decode: decoding_buffer=", data);
loggers::get_instance().log_msg(">>> uppertester_geonetworking_codec::decode (4): ", data);
 
/*const unsigned char* ptr = static_cast<const unsigned char*>(data);
if (*ptr == uppertester_geonetworking_codec::c_utDenmInitializeResult) {
/branches/STF525/ccsrc/Protocols/UpperTester/uppertester_geonetworking_codec.hh
29,6 → 29,7
Record_Type,
Record_Type>
{
public:
const unsigned char c_utGnInitialize = 0x00;
const unsigned char c_utGnInitializeResult = 0x01;
const unsigned char c_utGnChangePosition = 0x02;
40,6 → 41,7
const unsigned char c_utGnTrigger_Shb = 0x53;
const unsigned char c_utGnTrigger_Tsb = 0x54;
 
private:
int encode_ (const Base_Type& type, const TTCN_Typedescriptor_t& field_descriptor, TTCN_Buffer& encoding_buffer);
 
public: