Commit dd4d8327 authored by Yann Garcia's avatar Yann Garcia

Create project structure

parent 93af77e9
#include "LibItsHttp_MessageBodyTypes.hh"
#include "http_codec.hh"
#include "loggers.hh"
namespace LibItsHttp__EncdecDeclarations {
BITSTRING fx__enc__http__message(const LibItsHttp__TypesAndValues::HttpMessage& p) {
loggers::get_instance().log_msg(">>> fx__enc__http__message: ", (const Base_Type&)p);
OCTETSTRING os;
http_codec codec;
codec.encode(p, os);
return oct2bit(os);
}
INTEGER fx__dec__http__message(BITSTRING& pdu, LibItsHttp__TypesAndValues::HttpMessage& p) {
loggers::get_instance().log_msg(">>> fx__dec__http__message: ", pdu);
OCTETSTRING os = bit2oct(pdu);
http_codec codec;
codec.decode(os, p);
return 0;
}
} // End of namespace LibItsHttp__EncdecDeclarations
#include "LibMec_EncdecDeclarations.hh"
#include "loggers.hh"
namespace LibMec__EncdecDeclarations {
BITSTRING fx__enc__LocationRequest__UserInfo(const LibMec__SIPTypesAndValues::Request& p) {
loggers::get_instance().log_msg(">>> fx__enc__UserInfo: ", p);
float duration;
std::string tag("fx__enc__Request");
loggers::get_instance().set_start_time(tag);
OCTETSTRING os;
// sip_codec_request codec;
// if (codec.encode(p, os) == -1) {
// loggers::get_instance().warning("fx__enc__Request -1 result code was returned");
// return int2bit(0, 1);
// }
loggers::get_instance().set_stop_time(tag, duration);
return oct2bit(os);
}
INTEGER fx__dec__LocationRequest__UserInfo(BITSTRING& pdu, LibMec__SIPTypesAndValues::Request& p) {
loggers::get_instance().log_msg(">>> fx__dec__LocationRequest__UserInfo: ", pdu);
OCTETSTRING os = bit2oct(pdu);
// sip_codec_request codec;
// codec.decode(os, p);
return 0;
}
} // End of namespace LibMec__EncdecDeclarations
/*!
* \file base_time.hh
* \brief Header file for the control port base_time functionality.
* \author ETSI STF525
* \copyright ETSI Copyright Notification
* No part may be reproduced except as authorized by written permission.
* The copyright and the foregoing restriction extend to reproduction in all media.
* All rights reserved.
* \version 0.1
*/
#pragma once
#include <chrono>
/**
* \class base_time
* \brief This class provides time tools such as getting current time
*/
class base_time {
const unsigned long long its_base_time_ms = 1072915200000L; //! Base time 01/01/2004 12:00am in millseconds
static base_time* _instance;
private:
base_time() { }; //! Can not be created manually
public:
static inline base_time& get_instance();
virtual ~base_time() { if (_instance != nullptr) delete _instance; };
public:
inline const unsigned long long get_current_time_ms() const;
inline const unsigned long long get_its_base_time_ms() const;
inline const unsigned long long get_its_current_time_ms() const;
inline const unsigned long long get_its_current_time_us() const;
inline const unsigned long long get_its_current_time_mod_ms() const;
}; // End of class base_time
// static functions
base_time& base_time::get_instance() {
return (_instance != nullptr) ? *_instance : *(_instance = new base_time());
}
const unsigned long long base_time::get_current_time_ms() const {
return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
}
const unsigned long long base_time::get_its_base_time_ms() const {
return base_time::its_base_time_ms;
}
const unsigned long long base_time::get_its_current_time_ms() const {
return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count() - base_time::its_base_time_ms;
}
const unsigned long long base_time::get_its_current_time_us() const {
return std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch()).count() - base_time::its_base_time_ms * 1000;
}
const unsigned long long base_time::get_its_current_time_mod_ms() const {
return (std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count() - base_time::its_base_time_ms) % 65536;
}
/*!
* \file codec.hh
* \brief Header file for ITS abstract codec definition.
* \author ETSI STF525
* \copyright ETSI Copyright Notification
* No part may be reproduced except as authorized by written permission.
* The copyright and the foregoing restriction extend to reproduction in all media.
* All rights reserved.
* \version 0.1
*/
#pragma once
#include "params.hh"
class OCTETSTRING; //! Declare TITAN class
class CHARSTRING; //! Declare TITAN class
class BITSTRING; //! Declare TITAN class
/*!
* \class codec
* \brief This class provides the interface for all ITS codecs, include UT and AC codecs
* \abstract
*/
template<typename TPDUEnc, typename TPDUDec>
class codec {
protected:
params* _params; //! Reference to params stack
// \todo Use smart pointer std::unique_ptr<params>
public: //! \publicsection
/*!
* \fn codec();
* \brief Default constructor
* \todo Remove logs
*/
explicit codec() : _params(nullptr) { };
/*!
* \fn ~codec();
* \brief Default destructor
* \virtual
* \todo Remove logs
*/
virtual ~codec() { };
/*!
* \fn int encode(const TPDUEnc& msg, OCTETSTRING& data);
* \brief Encode typed message into an octet string
* \param[in] p_message The typed message to be encoded
* \param[out] p_data The encoding result
* \return 0 on success, -1 otherwise
* \pure
*/
virtual int encode(const TPDUEnc& p_message, OCTETSTRING& p_data) = 0;
/*!
* \fn int decode(const OCTETSTRING& p_, TPDUDec& p_message, params* p_params = NULL);
* \brief Encode typed message into an octet string format
* \param[in] p_data The message in its octet string
* \param[out] p_message The decoded typed message
* \return 0 on success, -1 otherwise
* \pure
*/
virtual int decode(const OCTETSTRING& p_, TPDUDec& p_message, params* p_params = NULL) = 0;
}; // End of class codec
/*!
* \file codec_factory.hh
* \brief Header file for ITS abstract protocol codec definition.
* \author ETSI STF525
* \copyright ETSI Copyright Notification
* No part may be reproduced except as authorized by written permission.
* The copyright and the foregoing restriction extend to reproduction in all media.
* All rights reserved.
* \version 0.1
*/
#pragma once
#include <string>
#include <map>
#include <vector>
#include <algorithm>
#include "codec.hh"
class Record_Type; //! TITAN forward declaration
/*!
* \class codec_factory
* \brief This class provides a factory class to create codec class instances
* \abstract
*/
class codec_factory {
public: //! \publicsection
/*!
* \fn codec();
* \brief Default constructor
*/
codec_factory() { };
/*!
* \fn codec* create_codec(const std::string & type, const std::string & param);
* \brief Create the codecs stack based on the provided codecs stack description (cf. remark)
* \param[in] p_type The provided codecs stack description
* \param[in] p_params Optional parameters
* \return 0 on success, -1 otherwise
* \remark The description below introduces codecs stack in case of ITS project:
* HTTP(codecs=xml:held_codec;html:html_codec,json:json_codec)/TCP(debug=1,server=httpbin.org,port=80,use_ssl=0)
* \pure
*/
virtual codec<Record_Type, Record_Type>* create_codec() = 0;
}; // End of class codec_factory
/*!
* \file codec_stack_builder.hh
* \brief Header file for ITS protocol stack builder.
* \author ETSI STF525
* \copyright ETSI Copyright Notification
* No part may be reproduced except as authorized by written permission.
* The copyright and the foregoing restriction extend to reproduction in all media.
* All rights reserved.
* \version 0.1
*/
#pragma once
#include "codec_factory.hh"
class Record_Type; //! TITAN forward declaration
/*!
* \class codec_stack_builder
* \brief This class provides a factory class to create Codec class instances
*/
class codec_stack_builder {
private: //! \privatesection
static codec_stack_builder* _instance; //! Smart pointer to the unique instance of the logger framework
std::map<std::string, codec_factory*> _codecs; //! The list of the registered \see t_codec factories
/*!
* \brief Default constructor
* Create a new instance of the codec_stack_builder class
* \private
*/
codec_stack_builder() { }; // can not be created manually
public: //! \publicsection
/*!
* \fn codec_stack_builder* get_instance();
* \brief Accessor for the unique instance of the logger framework
* \static
*/
static codec_stack_builder* get_instance() { return _instance ? _instance : _instance = new codec_stack_builder(); };
/*!
* \fn void register_codec_factory(const std::string & p_type, codec_factory<TPDUEnc, TPDUDec>* p_codec_factory);
* \brief Add a new codec factory
* \param[in] p_type The codec identifier (e.g. GN for the GeoNetworking codec...)
* \param[in] p_codec_factory A reference to the \see codec_factory
* \static
*/
static void register_codec_factory(const std::string & p_type, codec_factory* p_codec_factory) { codec_stack_builder::get_instance()->_register_codec_factory(p_type, p_codec_factory); };
private: //! \privatesection
/*!
* \fn void _register_codec_factory(const std::string & p_type, codec_factory<TPDUEnc, TPDUDec>* p_codec_factory);
* \brief Add a new codec factory
* \param[in] p_type The codec identifier (e.g. GN for the GeoNetworking codec...)
* \param[in] p_codec_factory A reference to the \see codec_factory
*/
void _register_codec_factory(const std::string & p_type, codec_factory* p_codec_factory) { _codecs[p_type] = p_codec_factory; };
public: //! \publicsection
/*!
* \fn codec* get_codec(const char* p_codec_name);
* \brief Retrieve the specified codec name from the list of the registered codecs
* \param[in] p_codec_name The codec indentifier
* \return The pointer to the codec object on success, nullptr otherwise
*/
inline codec<Record_Type, Record_Type>* get_codec(const char* p_codec_name) { // NOTE A virtual method cannot not be a template ==> polymorphism required here
typename std::map<std::string, codec_factory*>::const_iterator it = _codecs.find(p_codec_name);
if (it != _codecs.cend()) {
return it->second->create_codec();
}
return nullptr;
}
}; // End of class codec_stack_builder
This diff is collapsed.
/*!
* \file layer.hh
* \brief Header file for ITS abstract protocol layer definition.
* \author ETSI STF525
* \copyright ETSI Copyright Notification
* No part may be reproduced except as authorized by written permission.
* The copyright and the foregoing restriction extend to reproduction in all media.
* All rights reserved.
* \version 0.1
*/
#pragma once
#include <string>
#include <map>
#include <vector>
#include <algorithm>
#include "params.hh"
class OCTETSTRING; //! Forward declaration of TITAN class
class BITSTRING; //! Forward declaration of TITAN class
class CHARSTRING; //! Forward declaration of TITAN class
class INTEGER; //! Forward declaration of TITAN class
/*!
* \class layer
* \brief This class provides basic description of an ITS protocol layer
*/
class layer {
std::vector<layer*> upperLayers; //! List of the upper protocol layers
std::vector<layer*> lowerLayers; //! List of the lower protocol layers
protected:
std::string type; //! Type description, it indicates the protocol type (e.g. CAM, DENM, GN, ETH, PCAP...)
public: //! \publicsection
/*!
* \brief Default constructor
* Create a new instance of the layer class
*/
explicit layer() : upperLayers(), lowerLayers(), type(std::string("")) { };
/*!
* \brief Specialized constructor
* Create a new instance of the layer class with its type description
* \param[in] p_type The port type name (e.g. GN for the GeoNetworking layer)
* \remark This constructor is called by the layer factory
* \see layer_factory
*/
explicit layer(const std::string& p_type) : upperLayers(), lowerLayers(), type(std::string(p_type.begin(), p_type.end())) { };
/*!
* \brief Default destructor
* \todo Remove logs
*/
virtual ~layer() {
// Double linked list, only remove layers in lowerLayers from the lowest one
std::for_each(lowerLayers.rbegin(), lowerLayers.rend(), [](layer* it) { delete it; } );
lowerLayers.clear();
upperLayers.clear();
};
/*!
* \fn void delete_layer();
* \brief Delete this layer
* \todo To be implemented
*/
void delete_layer() { };
public: //! \publicsection
/*!
* \inline
* \fn void add_upper_layer(layer* p_layer);
* \brief Add a new layer in the list of the upper layer
* \param[in] p_layer The layer protocol to be removed
*/
inline void add_upper_layer(layer* p_layer) {
if (p_layer != NULL) {
upperLayers.push_back(p_layer);
p_layer->lowerLayers.push_back(this);
};
};
/*!
* \fn void remove_upper_layer(layer* p_layer);
* \brief Remove the specified upper layer protocol from the list of the upper layer
* \param[in] p_layer The layer protocol to be removed
* \todo To be implemented
*/
void remove_upper_layer(layer* p_layer) { };
/*!
* \virtual
* \fn void send_data(OCTETSTRING& data, params& params);
* \brief Send bytes formated data to the lower layers
* \param[in] p_data The data to be sent
* \param[in] p_params Some parameters to overwrite default value of the lower layers parameters
* \todo Remove the logs
* \virtual
*/
virtual void send_data(OCTETSTRING& p_data, params& p_params) { };
/*!
* \virtual
* \fn void receive_data(OCTETSTRING& data, params& params);
* \brief Receive bytes formated data from the lower layers
* \param[in] p_data The bytes formated data received
* \param[in] p_params Some lower layers parameters values when data was received
* \todo Remove the logs
* \virtual
*/
virtual void receive_data(OCTETSTRING& p_data, params& p_params) { }
/*!
* \inline
* \fn const std::string& to_string();
* \brief Remove the specified upper layer protocol from the list of the upper layer
* \param[in] The layer protocol to be removed
*/
inline const std::string& to_string() const { return type; };
protected: //! \protectedsection
inline void to_all_layers(std::vector<layer*>&layers, OCTETSTRING& data, params& params) {
for (std::vector<layer*>::const_iterator it = layers.cbegin(); it != layers.cend(); ++it) {
layer* p = *it;
p->receive_data(data, params); // FIXME BUG I
} // End of 'for' statement
};
inline void receive_to_all_layers(OCTETSTRING& data, params& params) {
for (std::vector<layer*>::const_iterator it = upperLayers.cbegin(); it != upperLayers.cend(); ++it) {
layer* p = *it;
p->receive_data(data, params);
} // End of 'for' statement
};
inline void send_to_all_layers(OCTETSTRING& data, params& params) {
for (std::vector<layer*>::const_iterator it = lowerLayers.cbegin(); it != lowerLayers.cend(); ++it) {
layer* p = *it;
p->send_data(data, params);
} // End of 'for' statement
};
}; // End of class layer
/*!
* \file layer_factory.hh
* \brief Header file for ITS abstract protocol layer definition.
* \author ETSI STF525
* \copyright ETSI Copyright Notification
* No part may be reproduced except as authorized by written permission.
* The copyright and the foregoing restriction extend to reproduction in all media.
* All rights reserved.
* \version 0.1
*/
#pragma once
#include <string>
#include <map>
#include <vector>
#include <algorithm>
#include "layer.hh"
/*!
* \class layer_factory
* \brief This class provides a factory class to create layer class instances
* \abstract
*/
class layer_factory {
public: //! \publicsection
/*!
* \fn codec();
* \brief Default constructor
*/
layer_factory() {};
/*!
* \fn layer* create_layer(const std::string & type, const std::string & param);
* \brief Create the layers stack based on the provided layers stack description (cf. remark)
* \param[in] p_type The provided layers stack description
* \param[in] p_params Optional parameters
* \return 0 on success, -1 otherwise
* \remark The description below introduces layers stack in case of ITS project:
* CAM layer
* next_header : btpA|btpB (overwrite BTP.type)
* header_type : tsb|gbc
* header_sub_type : sh (single hop)
* DENM layer
* next_header : btpA|btpB (overwrite BTP.type)
* header_type : tsb|gbc
* BTP layer
* type : btpA|btpB
* destination port: dst_port
* source port : src_port
* device_mode : Set to 1 if the layer shall encapsulate upper layer PDU
* GN layer
* its_aid : ITS AID as defined by ETSI TS 102 965 V1.2.1. Default: 141
* ll_address : GeoNetworking address of the Test System
* latitude : latitude of the Test System
* longitude : longitude of the Test System
* beaconing : Set to 1 if GnLayer shall start beaconing
* Beaconing timer expiry : expiry (ms)
* device_mode : Set to 1 if the layer shall encapsulate upper layer PDU
* secured_mode : Set to 1 if message exchanges shall be signed
* encrypted_mode : Set to 1 if message exchanges shall be encrypted
* NOTE: For signed & encrypted message exchanges, both secured_mode and encrypted_mode shall be set to 1
* certificate : Certificate identifier the Test Adapter shall use
* secure_db_path : Path to the certificates and keys storage location
* hash : Hash algorithm to be used when secured mode is set
* Authorized values are SHA-256 or SHA-384
* Default: SHA-256
* signature : Signature algorithm to be used when secured mode is set
* Authorized values are NISTP-256, BP-256 and BP-384
* Default: NISTP-256
* cypher : Cyphering algorithm to be used when secured mode is set
* Ethernet layer
* mac_src :Source MAC address
* mac_bc :Broadcast address
* eth_type : Ethernet type
* Commsignia layer
* mac_src : Device MAC address, used to discard packets
* To indicate no filering, use the value 000000000000
* mac_bc : Broadcast address
* eth_type : Ethernet type, used to discard packets
* target_host : Device address
* target_port : Device port
* source_port : Test System port
* interface_id: Interface id, used to discard packets
* tx_power : TX power (dB)
* UDP layer (IP/UDP based on Pcap)
* dst_ip : destination IPv4 address (aa.bb.cc.dd)
* dst_port: destination port
* src_ip : source IPv4 address (aa.bb.cc.dd)
* src_port: source port
* Pcap layer
* mac_src : Source MAC address, used to exclude from capture the acket sent by the Test System
* filter : Pcap filter (compliant with tcpdump syntax)
* E.g. filter=and ether src 04e548000001
* Online mode:
* nic: Local NIC
* If set, online mode is used
* Offline mode (nic is present but not set):
* file : File to read
* frame_offset: Frame offset, used to skip packets with frame number < frame_offset
* time_offset : Time offset, used to skip packets with time offset < time_offset
* save_mode : 1 to save sent packet, 0 otherwise
* Here are some examples:
* GeoNetworking multiple component case:
* NodeB.geoNetworkingPort.params := "GN(ll_address=04e548000001,latitude=43551050,longitude=10298730,beaconing=0,expiry=1000,its_aid=141)/COMMSIGNIA(mac_src=04e548000001,mac_bc=FFFFFFFFFFFF,eth_type=8947,target_host=10.200.1.101,target_port=7942,source_port=7943,its_aid=141,interface_id=2,tx_power=-32)/UDP(dst_ip=192.168.56.1,dst_port=12346,src_ip=192.168.156.4,src_port=12345)/ETH(mac_src=04e548000001,mac_dst=0A0027000011,eth_type=0800)/PCAP(mac_src=04e548000001,file=/home/vagrant/TriesAndDelete/etsi_its/testdata/TC_AUTO_IOT_DENM_RWW_BV_01_short.pcap,filter=and (udp port 30000 or udp port 7943))"
NodeC.geoNetworkingPort.params := "GN(ll_address=70b3d5791b48,latitude=43551050,longitude=10298730,beaconing=0,expiry=1000,its_aid=141)/COMMSIGNIA(mac_src=70b3d5791b48,mac_bc=FFFFFFFFFFFF,eth_type=8947,target_host=10.200.1.101,target_port=7942,source_port=7943,its_aid=141,interface_id=2,tx_power=-32)/UDP(dst_ip=192.168.56.1,dst_port=12346,src_ip=192.168.156.4,src_port=12345)/ETH(mac_src=70b3d5791b48,mac_dst=0A0027000011,eth_type=0800)/PCAP(mac_src=70b3d5791b48,file=/home/vagrant/TriesAndDelete/etsi_its/testdata/TC_AUTO_IOT_DENM_RWW_BV_01_short.pcap,filter=and (udp port 30000 or udp port 7943))"
* NodeB.geoNetworkingPort.params := "GN(ll_address=04e548000001,latitude=43551050,longitude=10298730,beaconing=0,expiry=1000,its_aid=141)/ETH(mac_src=04e548000001,mac_dst=0A0027000011,eth_type=0800)/PCAP(mac_src=04e548000001,file=/home/vagrant/TriesAndDelete/etsi_its/testdata/TC_AUTO_IOT_DENM_RWW_BV_01.pcap,filter=and ether src 04e548000001)"
#NodeC.geoNetworkingPort.params := "GN(ll_address=70b3d5791b48,latitude=43551050,longitude=10298730,beaconing=0,expiry=1000,its_aid=141)/ETH(mac_src=70b3d5791b48,mac_dst=0A0027000011,eth_type=0800)/PCAP(mac_src=70b3d5791b48,file=/home/vagrant/TriesAndDelete/etsi_its/testdata/TC_AUTO_IOT_DENM_RWW_BV_01.pcap,filter=and ether src 70b3d5791b48)"
* UpperTester port based on UDP
* system.utPort.params := "UT_GN/UDP(dst_ip=192.168.1.1,dst_port=12346,src_ip=192.168.156.4,src_port=12345)/ETH(mac_src=026f8338c1e5,mac_dst=0A0027000011,eth_type=0800)/PCAP(mac_src=0800275c4959,nic=enp0s8,filter=and udp port 12346)"
* \pure
*/
virtual layer* create_layer(const std::string & p_type, const std::string & p_params) = 0;
}; // End of class layer_factory
/*!
* \file layer_stack_builder.hh
* \brief Header file for ITS protocol stack builder.
* \author ETSI STF525
* \copyright ETSI Copyright Notification
* No part may be reproduced except as authorized by written permission.
* The copyright and the foregoing restriction extend to reproduction in all media.
* All rights reserved.
* \version 0.1
*/
#pragma once
#include "layer_factory.hh"
/*!
* \class layer_stack_builder
* \brief This class provides a factory class to create Layer class instances
*/
class layer_stack_builder {
private: //! \privatesection
typedef std::map<std::string, layer_factory*> LayerFactoryMap;
static layer_stack_builder * _instance; //! Smart pointer to the unique instance of the logger framework
std::map<std::string, layer_factory*> _layer_factories; //! The list of the registered \see t_layer factories
/*!
* \brief Default constructor
* Create a new instance of the layer_stack_builder class
* \private
*/
layer_stack_builder(); // can not be created manually
public: //! \publicsection
/*!
* \fn layer_stack_builder* get_instance();
* \brief Accessor for the unique instance of the logger framework
* \static
*/
static layer_stack_builder* get_instance();
/*!
* \fn void register_layer_factory(const std::string & p_type, layer_factory* p_layer_factory);
* \brief Add a new layer factory
* \param[in] p_type The layer identifier (e.g. GN for the GeoNetworking layer...)
* \param[in] p_layer_factory A reference to the \see layer_factory
* \static
*/
static void register_layer_factory(const std::string & p_type, layer_factory* p_layer_factory);
private: //! \privatesection
/*!
* \fn void _register_layer_factory(const std::string & p_type, layer_factory* p_layer_factory);
* \brief Add a new layer factory
* \param[in] p_type The layer identifier (e.g. GN for the GeoNetworking layer...)
* \param[in] p_layer_factory A reference to the \see layer_factory
*/
void _register_layer_factory(const std::string & p_type, layer_factory* p_layer_factory);
public: //! \publicsection
/*!
* \fn layer* create_layer_stack(const char* p_layer_stack_description);
* \brief Add a new layer factory
* \param[in] p_layer_stack_description A textual description of the layer to create
* \return The created layer object on success, nullptr otherwise
*/
layer* create_layer_stack(const char* p_layer_stack_description);
}; // End of class layer_stack_builder
/*!
* \file loogers.hh
* \brief Header file for the logger framework.
* \author ETSI STF525
* \copyright ETSI Copyright Notification
* No part may be reproduced except as authorized by written permission.
* The copyright and the foregoing restriction extend to reproduction in all media.
* All rights reserved.
* \version 0.1
*/
#pragma once
#include <memory>
#include <map>
#include <string>
#include <ctime>
#include <cstdarg>
/**
class Base_Type;
class OCTETSTRING;
class TTCN_Buffer;
class TTCN_Logger;
enum TTCN_Logger::Severity;
extern void TTCN_error(const char *err_msg, ...) __attribute__ ((__format__ (__printf__, 1, 2), __noreturn__));
extern void TTCN_error_begin(const char *err_msg, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
extern void TTCN_error_end() __attribute__ ((__noreturn__));
void TTCN_warning(const char *warning_msg, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
extern void TTCN_warning_begin(const char *warning_msg, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
extern void TTCN_warning_end();
**/
using namespace std; // Required for isnan()
#include <TTCN3.hh>
/*!
* \class loggers
* \brief This class provides basic functionalities for an ITS dictionary
* \implements Singleton pattern
* \todo Remove reference to TTCN3.hh
*/
class loggers {