Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • cti-tools/titan-test-system-framework
1 result
Show changes
Commits on Source (44)
Showing
with 289 additions and 274 deletions
/*!
* \file base_time.hh
* \brief Header file for the control port base_time functionality.
* \brief Header file for base_time functionality.
* \author ETSI STF525
* \copyright ETSI Copyright Notification
* No part may be reproduced except as authorized by written permission.
......
......@@ -32,7 +32,7 @@ public: //! \publicsection
*/
codec_factory(){};
/*!
* \fn codec* create_codec(const std::string & type, const std::string & param);
* \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
......
......@@ -50,7 +50,7 @@ public: //! \publicsection
*/
virtual int encode(const TPDUEnc &p_message, OCTETSTRING &p_data) = 0;
/*!
* \fn int decode(const OCTETSTRING& p_, TPDUDec& p_message, params_its* p_params = NULL);
* \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
......
......@@ -38,24 +38,24 @@ public: //! \publicsection
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);
* \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) {
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);
* \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; };
void _register_codec_factory(const std::string& p_type, codec_factory *p_codec_factory) { _codecs[p_type] = p_codec_factory; };
public: //! \publicsection
/*!
......
......@@ -104,7 +104,7 @@ public:
* \param[in] p_value The string value
* \return The hexadecimal value
*/
std::string string_to_hexa(const std::string &p_value, const bool p_uppercase = false);
std::string string_to_hexa(const std::string& p_value, const bool p_uppercase = false);
/*!
* \brief Convert a bytes array int32_t an hexadecimal string
* \param[in] p_value The bytes array value
......@@ -116,7 +116,7 @@ public:
* \param[in] p_value The hexadecimal value
* \return The bytes array value
*/
std::vector<uint8_t> hexa_to_bytes(const std::string &p_value);
std::vector<uint8_t> hexa_to_bytes(const std::string& p_value);
/*!
* \brief Convert a time in time_t format into a string formated according to RFC 822, 1036, 1123, 2822
......@@ -279,7 +279,7 @@ public:
* \param[in] p_value The string value
* \return The bytes array value
*/
inline std::vector<uint8_t> string_to_bytes(const std::string &p_value) const {
inline std::vector<uint8_t> string_to_bytes(const std::string& p_value) const {
return std::vector<uint8_t>(p_value.begin(), p_value.end());
}; // End of string_to_bytes
......@@ -298,7 +298,7 @@ public:
* \param[in] p_value The string value
* \return The integer value
*/
inline int32_t string_to_int(const std::string &p_value) const {
inline int32_t string_to_int(const std::string& p_value) const {
return std::stoi(p_value);
// return atoi(p_value.c_str());
}; // End of string_to_int
......@@ -318,13 +318,13 @@ public:
* \brief Convert a string in to lower case
* \param[in/out] p_value The string value to convert
*/
inline void to_lower(std::string &p_value) { std::transform(p_value.begin(), p_value.end(), p_value.begin(), ::tolower); }
inline void to_lower(std::string& p_value) { std::transform(p_value.begin(), p_value.end(), p_value.begin(), ::tolower); }
/*!
* \brief Convert a string in to upper case
* \param[in/out] p_value The string value to convert
*/
inline void to_upper(std::string &p_value) { std::transform(p_value.begin(), p_value.end(), p_value.begin(), ::toupper); }
inline void to_upper(std::string& p_value) { std::transform(p_value.begin(), p_value.end(), p_value.begin(), ::toupper); }
public:
/*!
......@@ -333,7 +333,7 @@ public:
* \param[in] p_trim_chars The special characters to be omitted. Default: ' ' and TAB
* \return The new string value
*/
std::string trim(const std::string &p_value, const std::string &p_trim_chars = " \t");
std::string trim(const std::string& p_value, const std::string& p_trim_chars = " \t");
/*!
* \brief Convert the provided string into a list of arguments
......@@ -349,7 +349,7 @@ public:
* }
* \endcode
*/
std::vector<std::string> split(const std::string &p_value, const std::string &p_separator);
std::vector<std::string> split(const std::string& p_value, const std::string& p_separator);
/*!
* \brief Convert the provided string into a list of arguments
......@@ -364,24 +364,33 @@ public:
* }
* \endcode
*/
std::vector<std::string> split_arguments_line(const std::string &p_value);
std::vector<std::string> split_arguments_line(const std::string& p_value);
/*!
* \brief Replace string or character into the the provided string
* \param[in] p_value The original string value
* \param[in] p_from The pattern to be replaced
* \param[in] p_to The new pattern
* \return The modified string
*/
std::string replace(const std::string& p_value, const std::string& p_from, const std::string& p_to);
/*!
* \brief Convert the provided buffer into a Base64
* \param[in] p_value The buffer value
* \return The Base64 encoded buffert
*/
std::vector<unsigned char> buffer_to_base64(const std::vector<unsigned char> &p_value);
std::vector<unsigned char> buffer_to_base64(const std::vector<unsigned char> &p_value, const bool p_is_url = false);
/*!
* \brief Convert the provided Base64 buffer
* \param[in] p_value The buffer value
* \return The Base64 encoded buffert
*/
std::vector<unsigned char> base64_to_buffer(const std::vector<unsigned char> &p_value);
std::vector<unsigned char> base64_to_buffer(const std::vector<unsigned char> &p_value, const bool p_remove_crlf = true);
static const std::string lut_u;
static const std::string lut_l;
static const std::string base64_enc_map;
static const std::string base64_enc_map[2];
}; // End of class converter
......@@ -47,7 +47,7 @@ public: //! \publicsection
* \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())){};
explicit layer(const std::string& p_type) : upperLayers(), lowerLayers(), type(std::string(p_type.begin(), p_type.end())){};
/*!
* \brief Default destructor
......@@ -102,7 +102,7 @@ public: //! \publicsection
/*!
* \virtual
* \fn void receive_data(OCTETSTRING& data, params_its& params);
* \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
......@@ -117,7 +117,7 @@ public: //! \publicsection
* \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; };
inline const std::string& to_string() const { return type; };
protected: //! \protectedsection
inline void to_all_layers(std::vector<layer *> &layers, OCTETSTRING &data, params &params) {
......
......@@ -30,58 +30,16 @@ public: //! \publicsection
*/
layer_factory(){};
/*!
* \fn layer* create_layer(const std::string & type, const std::string & param);
* \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
......@@ -99,23 +57,7 @@ public: //! \publicsection
* 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;
virtual layer *create_layer(const std::string& p_type, const std::string& p_params) = 0;
}; // End of class layer_factory
......@@ -38,22 +38,22 @@ public: //! \publicsection
static layer_stack_builder *get_instance();
/*!
* \fn void register_layer_factory(const std::string & p_type, layer_factory* p_layer_factory);
* \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);
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);
* \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);
void _register_layer_factory(const std::string& p_type, layer_factory *p_layer_factory);
public: //! \publicsection
/*!
......
#pragma once
#include "params.hh"
class OCTETSTRING;
class CHARSTRING;
class BITSTRING;
struct asn_TYPE_descriptor_s;
class asn1_recode_oer {
protected:
int xer2oer(const asn_TYPE_descriptor_s &td, TTCN_Buffer &buf);
int oer2xer(const asn_TYPE_descriptor_s &td, TTCN_Buffer &buf);
int recode(const asn_TYPE_descriptor_s &td, int from, int to, TTCN_Buffer &buf);
};
template <typename TPDU> class oer_codec : public asn1_recode_oer {
public:
virtual int encode(const TPDU &msg, BITSTRING &bits) = 0;
virtual int decode(const BITSTRING &bits, TPDU &msg) = 0;
protected:
inline int _decode(const TTCN_Typedescriptor_t &ttcn, const asn_TYPE_descriptor_s &td, const BITSTRING &p_data, TPDU &msg) {
TTCN_Buffer buf(bit2oct(p_data));
TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);
int rc = oer2xer(td, buf);
if (rc > 0) {
msg.decode(ttcn, buf, TTCN_EncDec::CT_BER, BER_ACCEPT_ALL);
rc = buf.get_len();
}
return rc;
}
inline int _encode(const TTCN_Typedescriptor_t &ttcn, const asn_TYPE_descriptor_s &td, const TPDU &msg, BITSTRING &p_data) {
int rc = -1;
TTCN_Buffer buf;
TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);
msg.encode(ttcn, buf, TTCN_EncDec::CT_BER, BER_ENCODE_DER);
if (buf.get_len() > 0) {
rc = xer2oer(td, buf);
if (rc > 0) {
p_data = oct2bit(OCTETSTRING(buf.get_len(), buf.get_data()));
}
}
return rc;
}
};
#endif
......@@ -35,14 +35,15 @@ public: //! \publicsection
static const std::string& nic; //! Network Interface Card parameter name
static const std::string& server; //! HTTP server address (e.g. www.etsi.org)
static const std::string& port; //! HTTP server port. Default: 80
static const std::string& server; //! Remote server address (e.g. www.etsi.org)
static const std::string& port; //! Remote server port. Default: 80
static const std::string& use_ssl; //! Set to 1 to use SSL to communicate with the HTTP server. Default: false
static const std::string& mutual_auth; //! Set to 1 to use mutual authentication. Default: false
static const std::string& trusted_ca_list; //! List of trusted CA certificates
static const std::string& certificate; //! Chain of certificates
static const std::string& privkey; //! Certificate private key
static const std::string& server_mode; //! Does the test sytem acting as a server. Default: 0
static const std::string& local_server; //! Local server address (e.g. localhost)
static const std::string& local_port; //! Local listener port. Default: 80
static const std::string& method; //! HTTP method type. Default: POST
......
/*!
* \file per_codec.hh
* \brief Header file for TITAN message to ASN.1 PER message codec.
* \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 "asn1_recode_per.hh"
#include "params.hh"
class BITSTRING; //! Forward declaration of TITAN class
class TTCN_Typedescriptor_t; //! Forward declaration of TITAN class
struct asn_TYPE_descriptor_s; //! Declare asn1c class
/*!
* \class per_codec
* \brief This class provides the interface for all ASN.1 PER codecs.
* \remark This class uses asn1c external tool
*/
template <typename TPDU> class per_codec : public asn1_recode_per {
public: //! \publicsection
/*!
* \fn int encode(const TPDU& p_message, BITSTRING& p_bitstring);
* \brief Encode TITAN message into ASN.1 PER message
* \param[in] p_message The PDU message to encode
* \param[out] p_bitstring The encoded PDU message in bit string format
* \pure
*/
virtual int encode(const TPDU &p_message, BITSTRING &p_bitstring) = 0;
/*!
* \fn int decode(const BITSTRING& p_bitstring, TPDU& p_message);
* \brief Decode ASN.1 PER message into TITAN message
* \param[in] p_bitstring The network message in bit string format to decode
* \param[out] p_message The PDU message
* \pure
*/
virtual int decode(const BITSTRING &p_bitstring, TPDU &p_message) = 0;
protected: //! \protectedsection
int _decode(const TTCN_Typedescriptor_t &ttcn, const asn_TYPE_descriptor_s &td, const BITSTRING &p_data, TPDU &msg);
int _encode(const TTCN_Typedescriptor_t &ttcn, const asn_TYPE_descriptor_s &td, const TPDU &msg, BITSTRING &p_data);
}; // End of class per_codec
#include "per_codec.t.hh"
#include <TTCN3.hh>
template <class TPDU> int per_codec<TPDU>::_decode(const TTCN_Typedescriptor_t &ttcn, const asn_TYPE_descriptor_s &td, const BITSTRING &p_data, TPDU &msg) {
TTCN_Buffer buf(bit2oct(p_data));
TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);
int rc = per2ber(td, buf);
if (rc > 0) {
msg.decode(ttcn, buf, TTCN_EncDec::CT_BER, BER_ACCEPT_ALL);
rc = buf.get_len();
}
return rc;
}
template <class TPDU> int per_codec<TPDU>::_encode(const TTCN_Typedescriptor_t &ttcn, const asn_TYPE_descriptor_s &td, const TPDU &msg, BITSTRING &p_data) {
int rc = -1;
TTCN_Buffer buf;
TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);
msg.encode(ttcn, buf, TTCN_EncDec::CT_BER, BER_ENCODE_DER);
if (buf.get_len() > 0) {
rc = ber2per(td, buf);
if (rc > 0) {
p_data = oct2bit(OCTETSTRING(buf.get_len(), buf.get_data()));
}
}
return rc;
}
......@@ -35,8 +35,8 @@ public:
};
public:
void add_item(const std::string &type, TItem *f);
TItem *get_item(const std::string &type);
void add_item(const std::string& type, TItem *f);
TItem *get_item(const std::string& type);
}; // End of class registration
template <typename TItem> registration<TItem> *registration<TItem>::_instance = nullptr;
......@@ -46,9 +46,9 @@ template <typename TItem> registration<TItem> &registration<TItem>::get_instance
return (_instance != nullptr) ? *_instance : *(_instance = new registration());
}
template <typename TItem> void registration<TItem>::add_item(const std::string &type, TItem *f) { _items[type] = f; }
template <typename TItem> void registration<TItem>::add_item(const std::string& type, TItem *f) { _items[type] = f; }
template <typename TItem> TItem *registration<TItem>::get_item(const std::string &type) {
template <typename TItem> TItem *registration<TItem>::get_item(const std::string& type) {
typename std::map<std::string, TItem *>::const_iterator it = _items.find(type);
if (it == _items.cend()) {
return nullptr;
......
......@@ -39,7 +39,7 @@ public: //! \publicsection
* \remark This constructor is called by the layer factory
* \see layer_factory
*/
explicit t_layer(const std::string &p_type) : layer(p_type), upperPorts(){};
explicit t_layer(const std::string& p_type) : layer(p_type), upperPorts(){};
/*!
* \inline
* \fn void add_upper_port(TPort * p_port);
......
/*!
* \file base_time.cc
* \brief Source file for the control port base_time functionality.
* \brief Source file base_time functionality.
* \author ETSI STF525
* \copyright ETSI Copyright Notification
* No part may be reproduced except as authorized by written permission.
......
#include "converter.hh"
#include <stdexcept>
converter *converter::instance = NULL;
uint16_t converter::swap(const uint16_t p_value) {
......@@ -14,7 +16,7 @@ uint32_t converter::swap(const uint32_t p_value) {
const std::string converter::lut_u = "0123456789ABCDEF";
const std::string converter::lut_l = "0123456789abcdef";
std::string converter::string_to_hexa(const std::string &p_value, const bool p_uppercase) {
std::string converter::string_to_hexa(const std::string& p_value, const bool p_uppercase) {
std::string input(p_value);
std::for_each(input.begin(), input.end(), [](char &c) { c = std::toupper(c); });
......@@ -40,22 +42,22 @@ std::string converter::string_to_hexa(const std::string &p_value, const bo
}
std::string converter::bytes_to_hexa(const std::vector<uint8_t> &p_value, const bool p_uppercase) {
std::string ret;
ret.assign(p_value.size() * 2, ' ');
std::string out;
out.assign(p_value.size() * 2, ' ');
if (p_uppercase) { // TODO Use pointer to reduce code size
for (size_t i = 0; i < p_value.size(); i++) {
uint8_t c = p_value[i];
ret[i * 2] = lut_u[c >> 4];
ret[i * 2 + 1] = lut_u[c & 0xF];
out[i * 2] = lut_u[c >> 4];
out[i * 2 + 1] = lut_u[c & 0xF];
}
} else {
for (size_t i = 0; i < p_value.size(); i++) {
uint8_t c = p_value[i];
ret[i * 2] = lut_l[c >> 4];
ret[i * 2 + 1] = lut_l[c & 0xF];
out[i * 2] = lut_l[c >> 4];
out[i * 2 + 1] = lut_l[c & 0xF];
}
}
return ret;
return out;
}
inline uint8_t char2byte(const char p_ch) {
......@@ -68,7 +70,7 @@ inline uint8_t char2byte(const char p_ch) {
return s;
}
std::vector<uint8_t> converter::hexa_to_bytes(const std::string &p_value) {
std::vector<uint8_t> converter::hexa_to_bytes(const std::string& p_value) {
// Sanity check
std::vector<uint8_t> output;
size_t i = 0, idx = 0, outlen = (p_value.length() + 1) / 2;
......@@ -100,7 +102,7 @@ std::string converter::time_to_string(const struct tm &p_time) {
return std::string(buffer);
}
std::string converter::trim(const std::string &str, const std::string &whitespace) {
std::string converter::trim(const std::string& str, const std::string& whitespace) {
size_t strBegin = str.find_first_not_of(whitespace);
if (strBegin == std::string::npos)
return ""; // no content
......@@ -111,7 +113,7 @@ std::string converter::trim(const std::string &str, const std::string &whitespac
return str.substr(strBegin, strRange);
}
std::vector<std::string> converter::split(const std::string &p_value, const std::string &p_separator) {
std::vector<std::string> converter::split(const std::string& p_value, const std::string& p_separator) {
std::vector<std::string> output;
std::size_t current, previous = 0;
current = p_value.find(p_separator);
......@@ -125,7 +127,7 @@ std::vector<std::string> converter::split(const std::string &p_value, const std:
return output;
}
std::vector<std::string> converter::split_arguments_line(const std::string &p_value) {
std::vector<std::string> converter::split_arguments_line(const std::string& p_value) {
std::vector<std::string> output;
std::string line = trim(p_value);
if (!line.empty() && (line[0] == '-')) { // Valid command line
......@@ -147,49 +149,122 @@ std::vector<std::string> converter::split_arguments_line(const std::string &p_va
return output;
}
const std::string converter::base64_enc_map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const std::string converter::base64_enc_map[2] = {
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
};
/**
* @brief Return the position of chr within base64_encode()
* @param[in] chr
* @return Return the position of chr within base64_encode()
*/
static unsigned char pos_of_char(const unsigned char chr) {
if ((chr >= 'A' && chr <= 'Z')) {
return static_cast<unsigned char>(chr - 'A');
} else if ((chr >= 'a' && chr <= 'z')) {
return static_cast<unsigned char>(chr - 'a' + ('Z' - 'A') + 1);
} else if ((chr >= '0' && chr <= '9')) {
return static_cast<unsigned char>(chr - '0' + ('Z' - 'A') + ('z' - 'a') + 2);
} else if ((chr == '+' || chr == '-')) {
return 62; // Be liberal with input and accept both url ('-') and non-url ('+') base 64 characters (
} else if ((chr == '/' || chr == '_')) {
return 63; // Idem for '/' and '_'
} else {
throw std::runtime_error("Input is not valid base64-encoded data.");
}
}
static std::string insert_linebreaks(std::string str, size_t distance) {
if (!str.length()) {
return "";
}
size_t pos = distance;
while (pos < str.size()) {
str.insert(pos, "\n");
pos += distance + 1;
}
return str;
}
std::string converter::replace(const std::string& p_value, const std::string& p_from, const std::string& p_to) {
size_t start_pos = 0;
std::string str(p_value);
while((start_pos = str.find(p_from, start_pos)) != std::string::npos) {
str.replace(start_pos, p_from.length(), p_to);
start_pos += p_to.length(); // Handles case where 'p_to' is a substring of 'p_from'
}
return str;
}
std::vector<unsigned char> converter::buffer_to_base64(const std::vector<unsigned char> &p_value, const bool p_is_url) {
const std::string& base64_enc_map_ = converter::base64_enc_map[(p_is_url) ? 1 : 0];
const unsigned char trailing_char = (p_is_url) ? '.' : '=';
std::vector<unsigned char> converter::buffer_to_base64(const std::vector<unsigned char> &p_value) {
std::vector<unsigned char> out;
//out.resize((p_value.size() + 2) / 3 * 4);
unsigned int pos = 0;
while (pos < p_value.size()) {
out.push_back(base64_enc_map_[(p_value[pos + 0] & 0xfc) >> 2]);
if (pos+1 < p_value.size()) {
out.push_back(base64_enc_map_[((p_value[pos + 0] & 0x03) << 4) + ((p_value[pos + 1] & 0xf0) >> 4)]);
int val = 0, valb = -6;
for (unsigned char c : p_value) {
val = (val << 8) + c;
valb += 8;
while (valb >= 0) {
out.push_back(converter::base64_enc_map[(val >> valb) & 0x3F]);
valb -= 6;
if (pos+2 < p_value.size()) {
out.push_back(base64_enc_map_[((p_value[pos + 1] & 0x0f) << 2) + ((p_value[pos + 2] & 0xc0) >> 6)]);
out.push_back(base64_enc_map_[ p_value[pos + 2] & 0x3f]);
} else {
out.push_back(base64_enc_map_[(p_value[pos + 1] & 0x0f) << 2]);
out.push_back(trailing_char);
}
} else {
out.push_back(base64_enc_map_[(p_value[pos + 0] & 0x03) << 4]);
out.push_back(trailing_char);
out.push_back(trailing_char);
}
pos += 3;
} // End of 'while' statement
} // End of 'for' statement
if (valb > -6) {
out.push_back(converter::base64_enc_map[((val << 8) >> (valb + 8)) & 0x3F]);
}
while (out.size() % 4) {
out.push_back('=');
} // End of 'while' statement
return out;
}
std::vector<unsigned char> converter::base64_to_buffer(const std::vector<unsigned char> &p_value) {
std::vector<unsigned char> out;
std::vector<unsigned char> converter::base64_to_buffer(const std::vector<unsigned char> &p_value, const bool p_remove_crlf) {
std::vector<int> T(256, -1);
for (int i = 0; i < 64; i++) {
T[converter::base64_enc_map[i]] = i;
if (p_value.size() == 0) {
return std::vector<unsigned char>();
}
int val = 0, valb = -8;
for (unsigned char c : p_value) {
if (T[c] == -1) {
break;
}
val = (val << 6) + T[c];
valb += 6;
if (valb >= 0) {
out.push_back((unsigned char)char((val >> valb) & 0xFF));
valb -= 8;
std::vector<unsigned char> value(p_value);
if (p_remove_crlf) {
value.erase(std::remove(value.begin(), value.end(), '\r'), value.end());
value.erase(std::remove(value.begin(), value.end(), '\n'), value.end());
}
std::vector<unsigned char> out;
//out.resize(value.size() / 4 * 3);
size_t pos = 0;
while (pos < value.size()) {
size_t pos_of_char_1 = pos_of_char(value[pos + 1]);
out.push_back(((pos_of_char(value[pos])) << 2 ) + ( (pos_of_char_1 & 0x30 ) >> 4));
if ((pos + 2 < value.size()) && // Check for data that is not padded with equal signs (which is allowed by RFC 2045)
value[pos + 2] != '=' &&
value[pos + 2] != '.' // accept URL-safe base 64 strings, too, so check for '.' also.
) {
//Emit a chunk's second byte (which might not be produced in the last chunk).
unsigned int pos_of_char_2 = pos_of_char(value[pos + 2]);
out.push_back(((pos_of_char_1 & 0x0f) << 4) + ((pos_of_char_2 & 0x3c) >> 2));
if ((pos + 3 < value.size()) && value[pos + 3] != '=' && value[pos + 3] != '.' ) {
// Emit a chunk's third byte (which might not be produced in the last chunk).
out.push_back(((pos_of_char_2 & 0x03 ) << 6) + pos_of_char(value[pos + 3]));
}
}
} // End of 'for' statement
pos += 4;
} // End of 'while' statement
return out;
}
......@@ -10,17 +10,17 @@ layer_stack_builder *layer_stack_builder::_instance = NULL;
// static functions
layer_stack_builder *layer_stack_builder::get_instance() { return _instance ? _instance : _instance = new layer_stack_builder(); }
void layer_stack_builder::register_layer_factory(const std::string &p_type, layer_factory *p_layer_factory) {
void layer_stack_builder::register_layer_factory(const std::string& p_type, layer_factory *p_layer_factory) {
layer_stack_builder::get_instance()->_register_layer_factory(p_type, p_layer_factory);
}
// member functions
layer_stack_builder::layer_stack_builder() {}
void layer_stack_builder::_register_layer_factory(const std::string &p_type, layer_factory *p_layer_factory) { _layer_factories[p_type] = p_layer_factory; }
void layer_stack_builder::_register_layer_factory(const std::string& p_type, layer_factory *p_layer_factory) { _layer_factories[p_type] = p_layer_factory; }
layer *layer_stack_builder::create_layer_stack(const char *p_layer_stack_description) {
loggers::get_instance().log(">>> layer_stack_builder::create_layer_stack: %s", p_layer_stack_description);
loggers::get_instance().log(">>> layer_stack_builder::create_layer_stack: '%s'", p_layer_stack_description);
layer *entry = NULL; // Initial layer (the first declared)
layer *up = NULL; // Upper layer
......@@ -36,12 +36,12 @@ layer *layer_stack_builder::create_layer_stack(const char *p_layer_stack_descrip
m[2].str().c_str(), m[3].str().c_str());
LayerFactoryMap::iterator i = _layer_factories.find(m[1].str());
if (i == _layer_factories.end()) {
loggers::get_instance().error("layer_stack_builder::create_layer_stack: %s: Unknown layer type", m[1].str().c_str());
loggers::get_instance().error("layer_stack_builder::create_layer_stack: '%s': Unknown layer type", m[1].str().c_str());
}
loggers::get_instance().log("layer_stack_builder::create_layer_stack: Create layer %s, %s", m[1].str().c_str(), m[3].str().c_str());
layer *l = i->second->create_layer(m[1].str(), m[3].str());
if (NULL == l) {
loggers::get_instance().error("layer_stack_builder::create_layer_stack: %s: Layer creation error", m[1].str().c_str());
loggers::get_instance().error("layer_stack_builder::create_layer_stack: '%s': Layer creation error", m[1].str().c_str());
}
loggers::get_instance().log("layer_stack_builder::create_layer_stack: Setup layers for %s - %p", l->to_string().c_str(), (void*)l);
......
......@@ -37,6 +37,7 @@ const std::string& params::certificate = std::string("certificate");
const std::string& params::privkey = std::string("privkey");
const std::string& params::server_mode = std::string("server_mode");
const std::string& params::local_server = std::string("local_server");
const std::string& params::local_port = std::string("local_port");
const std::string& params::method = std::string("method");
......@@ -51,7 +52,7 @@ void params::convert(params &p_param, const std::string p_parameters) {
if (p_parameters.length() == 0) {
return;
}
loggers::get_instance().log(">>> params::convert: %s", p_parameters.c_str());
loggers::get_instance().log(">>> params::convert: '%s'", p_parameters.c_str());
// Extract parameters
try {
std::regex rgx("(\\w+)=(.*?)(,|$)");
......
#include "LibHelpers_Functions.hh"
#include <math.h>
#include <sstream>
#include <iomanip>
#include <random>
#include "LibHelpers_Functions.hh"
#include "base_time.hh"
#include "converter.hh"
#include "loggers.hh"
#include "xml_converters.hh"
#ifndef M_PI
#define M_PI 3.14159265358979323846
......@@ -29,7 +35,7 @@ namespace LibHelpers__Functions {
* @see function f_getMinuteOfTheYear() return MinuteOfTheYear
*/
INTEGER fx__getMinuteOfTheYear() {
// TODO: this is just a sceleton. fill in the function
// TODO: this is just a skeleton. fill in the function
return 0;
}
......@@ -39,8 +45,113 @@ namespace LibHelpers__Functions {
* @see function f_getDSecond() return DSecond
*/
INTEGER fx__getDSecond() {
// TODO: this is just a sceleton. fill in the function
// TODO: this is just a skeleton. fill in the function
return 0;
}
/**
* @desc Encode into Base64
* @return p_to_encode - The buffer to be encoded
* @see function f_enc_base64(in octetstring p_to_encode) return octetstring
*/
OCTETSTRING fx__enc__base64(const OCTETSTRING& p_to_encode) {
loggers::get_instance().log_msg(">>> fx__enc__base64: ", p_to_encode);
const std::vector<unsigned char> to_encode(static_cast<const unsigned char*>(p_to_encode), static_cast<const unsigned char*>(p_to_encode) + p_to_encode.lengthof());
std::vector<unsigned char> b64 = converter::get_instance().buffer_to_base64(to_encode);
OCTETSTRING os(b64.size(), b64.data());
loggers::get_instance().log_msg("<<< fx__enc__base64: ", os);
return os;
}
/**
* @desc Decode from Base64
* @return p_to_decode - The buffer to be decoded
* @see function f_dec_base64(in octetstring p_to_decode) return octetstring
*/
OCTETSTRING fx__dec__base64(const OCTETSTRING& p_to_decode) {
loggers::get_instance().log_msg(">>> fx__dec__base64: ", p_to_decode);
const std::vector<unsigned char> to_decode(static_cast<const unsigned char*>(p_to_decode), static_cast<const unsigned char*>(p_to_decode) + p_to_decode.lengthof());
std::vector<unsigned char> b64 = converter::get_instance().base64_to_buffer(to_decode);
OCTETSTRING os(b64.size(), b64.data());
loggers::get_instance().log_msg("<<< fx__dec__base64: ", os);
return os;
}
static unsigned char random_char() {
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(0, 255);
return static_cast<unsigned char>(dis(gen));
}
static std::string generate_hex(const unsigned int len) {
std::stringstream ss;
for(auto i = 0; i < len; i++) {
auto rc = random_char();
std::stringstream hexstream;
hexstream << std::hex << int(rc);
auto hex = hexstream.str();
ss << (hex.length() < 2 ? '0' + hex : hex);
}
return ss.str();
}
/**
* @brief Generate a new UUID
* @return The UUID in string format on success, a null string otherwise
*/
CHARSTRING fx__generate__uuid() { // ddb848c4-f7fd-445f-bdc8-033d15d7c528
loggers::get_instance().log(">>> fx__generate__uuid");
std::stringstream ss;
ss << generate_hex(6) << "-";
ss << generate_hex(2) << "-";
ss << generate_hex(2) << "-";
ss << generate_hex(2) << "-";
ss << generate_hex(6);
CHARSTRING uuid(ss.str().c_str());
loggers::get_instance().log_msg("fx__generate__uuid: ", uuid);
return uuid;
}
/**
* @brief Retrieve the current local date/time formatted as yyyy-mm-ddThh:mm:ss.lll+nn:00
* @return The the current date/time on success, a null string otherwise
*/
CHARSTRING fx__get__current__date__time(const INTEGER& p__shift__time) { //2018-01-18T13:19:35.367+01:00
loggers::get_instance().log(">>> fx__get__current__date__time");
time_t t = std::time(nullptr);
if (p__shift__time != 0) {
t += static_cast<int>(p__shift__time);
}
auto tm = *std::localtime(&t);
std::ostringstream oss;
oss << std::put_time(&tm, "%FT%TZ");//%FT%T%Z
CHARSTRING dt(oss.str().c_str());
loggers::get_instance().log_msg("fx__get__current__date__time: ", dt);
return dt;
}
/**
* @brief Retrieve the local date/time in the past formatted as yyyy-mm-ddThh:mm:ss.lll+nn:00
* @return The the current date/time on success, a null string otherwise
*/
CHARSTRING fx__get__current__date__time__past() { //2018-01-18T13:19:35.367+01:00
loggers::get_instance().log(">>> fx__get__current__date__time");
time_t t = std::time(nullptr);
auto tm = *std::localtime(&t);
std::ostringstream oss;
oss << std::put_time(&tm, "%FT%TZ");//%FT%T%Z
CHARSTRING dt(oss.str().c_str());
loggers::get_instance().log_msg("fx__get__current__date__time: ", dt);
return dt;
}
} // namespace LibHelpers__Functions
......@@ -2,8 +2,8 @@
#include "loggers.hh"
ethernet_layer::ethernet_layer(const std::string & p_type, const std::string & p_param) : layer(p_type), _params() {
loggers::get_instance().log(">>> ethernet_layer::ethernet_layer: %s, %s", to_string().c_str(), p_param.c_str());
ethernet_layer::ethernet_layer(const std::string& p_type, const std::string& p_param) : layer(p_type), _params() {
loggers::get_instance().log(">>> ethernet_layer::ethernet_layer: '%s', %s", to_string().c_str(), p_param.c_str());
// Setup parameters
params::convert(_params, p_param);
params::const_iterator it = _params.find("mac_src");
......@@ -68,7 +68,7 @@ void ethernet_layer::receive_data(OCTETSTRING& p_data, params& p_params) {
// Extract ethertype
OCTETSTRING proto = OCTETSTRING(2, 2 + static_cast<const unsigned char *>(p_data));
//loggers::get_instance().log_msg("ethernet_layer::receive_data: proto: ", proto);
OCTETSTRING data = OCTETSTRING(data.lengthof() - 14, 14 + static_cast<const unsigned char *>(p_data));
OCTETSTRING data = OCTETSTRING(p_data.lengthof() - 14, 14 + static_cast<const unsigned char *>(p_data));
// Update params
CHARSTRING s = oct2str(dst);
p_params.insert(std::pair<std::string, std::string>(params::mac_dst, std::string(static_cast<const char *>(s))));
......