git-subtree-dir: libs/CommService git-subtree-split: 7ccc0fce88bbc5969df060058cf0fb57abe3bcf9
386 lines
13 KiB
C++
386 lines
13 KiB
C++
#pragma once
|
|
/*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
/**
|
|
* @file
|
|
* @copyright 2022 MPLv2
|
|
*/
|
|
#include <chrono>
|
|
#include <cstdint>
|
|
#include <vector>
|
|
#include <cstring>
|
|
#include <BC/endianess.hpp>
|
|
#include <string>
|
|
#include <stdexcept>
|
|
#include <map>
|
|
|
|
/**
|
|
* @brief main namespace of libbattle-com++
|
|
*
|
|
* Main namespace of the libbattle-com++, everything concerning the library can be found
|
|
* in this namespace
|
|
*/
|
|
namespace BC
|
|
{
|
|
|
|
/**
|
|
* @brief Namespace for all BC wide DataTypes
|
|
*/
|
|
namespace DataTypes
|
|
{
|
|
|
|
/**
|
|
* @brief namespace for conversion functions for different datatypes
|
|
*/
|
|
namespace Convert
|
|
{
|
|
|
|
/*
|
|
* @brief template function to byte swap int/uint datatypes - used for endianess conversion
|
|
*
|
|
* @param v - pointer to a variable of some int/uint datatype - in place byte swapped
|
|
*/
|
|
template<typename T>
|
|
void swapBytes(T *v)
|
|
{
|
|
for (unsigned int i = 0; i < sizeof(T)/2; ++i)
|
|
{
|
|
std::swap(((char *)v)[i], ((char *)v)[sizeof(T)-1-i]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief template for converting of simple datatypes to a byte_array, including endianness conversion to big endian
|
|
*
|
|
* @param variable - the variable to convert to a byte vector, needs to be int/uint datatype
|
|
*
|
|
* @return the std::vector<unsigned char>
|
|
*/
|
|
template<typename T>
|
|
std::vector<unsigned char> fromSimpleToByteArray(T &variable)
|
|
{
|
|
std::vector<unsigned char> bytes;
|
|
bytes.clear();
|
|
bytes.resize(sizeof(T));
|
|
|
|
#ifndef IS_BIG_ENDIAN
|
|
T convVariable = variable;
|
|
swapBytes(&convVariable);
|
|
std::memcpy(bytes.data(),reinterpret_cast<const unsigned char*>(&convVariable),sizeof(T));
|
|
#else
|
|
std::memcpy(bytes.data(),reinterpret_cast<const unsigned char*>(&variable),sizeof(T));
|
|
#endif
|
|
|
|
|
|
|
|
return bytes;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief function to convert a std::string to an std::vector<unsigned char>
|
|
*
|
|
* for converting the string, first the length of the string is converted as
|
|
* an uint32_t into the std::vector to be able to correctly parse the string
|
|
* in a larger vector.
|
|
*
|
|
* @param variable - the std::string to convert
|
|
*
|
|
* @return the std::vector<unsigned char>
|
|
*/
|
|
std::vector<unsigned char> fromStringToByteArray(const std::string &variable);
|
|
|
|
|
|
/**
|
|
* @brief function to convert a std::vector<unsigned char> to an std::string
|
|
*
|
|
* this is the partner function to fromStringToByteArray. It takes the
|
|
* first 4 byte of the vector as an uint32_t string length identifier and
|
|
* uses the following length chars as the string
|
|
*
|
|
* @param v - the vector to convert to a string
|
|
* @return the string read from the vector
|
|
* @throw std::invalid_argument: "vector too short for <X> chars"
|
|
*/
|
|
std::string fromByteArrayToString(std::vector<unsigned char> &v);
|
|
|
|
/**
|
|
* @brief function to convert a std::vector<unsigned char> to an simple datatype
|
|
*
|
|
* this is the partner function to fromSimpleToByteArray.
|
|
* it extracts the simple datatype like int, double, etc. from the vector and
|
|
* returns it
|
|
*
|
|
* @param v - the vector to convert to a simple datatype
|
|
* @return simple datatype
|
|
* @throw std::invalid_argument: "the bytevector is too small to fit the datatype"
|
|
*/
|
|
template<typename T>
|
|
T fromByteArrayToSimple(std::vector<unsigned char> &bytes)
|
|
{
|
|
T convVariable;
|
|
if(bytes.size() < sizeof(T))
|
|
{
|
|
throw(std::invalid_argument(std::string(__FILE__) + ":" + std::string(__PRETTY_FUNCTION__) + ":" + std::to_string(__LINE__) + ": the bytevector is too small to fit the datatype"));
|
|
}
|
|
std::memcpy(reinterpret_cast<unsigned char*>(&convVariable),bytes.data(),sizeof(T));
|
|
#ifndef IS_BIG_ENDIAN
|
|
swapBytes(&convVariable);
|
|
#endif
|
|
return std::move(convVariable);
|
|
}
|
|
|
|
/**
|
|
* @brief function to convert a container of a simple datatype to a std::vector<unsigned char>
|
|
*
|
|
* this is the partner function to fromByteArrayToSimpleContainer.
|
|
* the number of container elements is prepended to the std::vector and the simple datatype
|
|
* elements follow.
|
|
*
|
|
* @param data - the container of a simple datatype
|
|
*
|
|
* @return the std::vector<unsigned char>;
|
|
*/
|
|
template<class T>
|
|
std::vector<unsigned char> fromSimpleContainerToByteArray(T &data)
|
|
{
|
|
std::vector<unsigned char> bytes;
|
|
std::vector<unsigned char> convert;
|
|
|
|
uint32_t size=data.size();
|
|
bytes=BC::DataTypes::Convert::fromSimpleToByteArray(size);
|
|
|
|
for(auto it = data.begin(); it!=data.end(); ++it)
|
|
{
|
|
convert=BC::DataTypes::Convert::fromSimpleToByteArray(*it);
|
|
bytes.insert(std::end(bytes), std::begin(convert), std::end(convert));
|
|
}
|
|
|
|
return bytes;
|
|
}
|
|
|
|
/**
|
|
* @brief function to convert a std::vector<unsigned char> to a container of simple datatype elements
|
|
*
|
|
* this is the partner function to fromSimpleContainerToByteArray. It takes the
|
|
* first 4 byte of the vector as an uint32_t element count and parses the all the elements
|
|
* from the vector.
|
|
*
|
|
* @param v - the vector to convert to a container of simple datatype elements
|
|
*
|
|
* @return the container
|
|
*/
|
|
template<class T, typename S>
|
|
T fromByteArrayToSimpleContainer(std::vector<unsigned char> &v)
|
|
{
|
|
T data;
|
|
uint32_t size = BC::DataTypes::Convert::fromByteArrayToSimple<S>(v);
|
|
v.erase(v.begin(), v.begin()+sizeof(size));
|
|
for(uint32_t i=0; i<size; i++)
|
|
{
|
|
S convert = BC::DataTypes::Convert::fromByteArrayToSimple<S>(v);
|
|
v.erase(v.begin(), v.begin()+sizeof(convert));
|
|
data.push_back(convert);
|
|
}
|
|
|
|
return std::move(data);
|
|
}
|
|
|
|
/**
|
|
* @brief function to convert a container of strings to a std::vector<unsigned char>
|
|
*
|
|
* @param data - the container of std::string
|
|
*
|
|
* @return the std::vector<unsigned char>
|
|
*/
|
|
template<class T>
|
|
std::vector<unsigned char> fromStringContainerToByteArray(T &data)
|
|
{
|
|
std::vector<unsigned char> bytes;
|
|
std::vector<unsigned char> convert;
|
|
|
|
uint32_t size=data.size();
|
|
bytes=BC::DataTypes::Convert::fromSimpleToByteArray(size);
|
|
|
|
for(auto it = data.begin(); it!=data.end(); ++it)
|
|
{
|
|
convert=BC::DataTypes::Convert::fromStringToByteArray(*it);
|
|
bytes.insert(std::end(bytes), std::begin(convert), std::end(convert));
|
|
}
|
|
|
|
return bytes;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief function to convert a std::vector<unsigned char> to a container of strings
|
|
*
|
|
* @param data - the container of std::string
|
|
*
|
|
* @return the std::vector<unsigned char>
|
|
*/
|
|
template<class T>
|
|
T fromByteArrayToStringContainer(std::vector<unsigned char> &v)
|
|
{
|
|
T data;
|
|
uint32_t size = BC::DataTypes::Convert::fromByteArrayToSimple<uint32_t>(v);
|
|
v.erase(v.begin(), v.begin()+sizeof(size));
|
|
|
|
for(uint32_t i=0; i<size; i++)
|
|
{
|
|
std::string convert = BC::DataTypes::Convert::fromByteArrayToString(v);
|
|
data.push_back(convert);
|
|
}
|
|
|
|
return std::move(data);
|
|
}
|
|
|
|
} // namespace Convert
|
|
|
|
|
|
|
|
/// type of the clock used by BC
|
|
using BCClockType = std::chrono::system_clock;
|
|
|
|
/// type of all time attributes throughout BC BCClockType::period
|
|
using BCTimeType = uint64_t;
|
|
|
|
/// the period of the clock within BC, can be different from the actual used clock
|
|
using BCPeriod = std::chrono::nanoseconds;
|
|
|
|
/// variable type for device/endpoint ids within libcms++
|
|
using deviceIdType = uint32_t;
|
|
|
|
/// enumeration variable for identifying major device/endpoint types.
|
|
enum deviceMajorType : uint32_t
|
|
{
|
|
/// device/endpoint is a radar
|
|
RADAR,
|
|
/// device/endpoint is a sonar
|
|
SONAR,
|
|
/// device/endpoint is a lidar
|
|
LIDAR,
|
|
/// device/endpoint is a camera
|
|
CAMERA,
|
|
/// device/endpoint is a threat avaluation process/device/software
|
|
THREAT_EVALUATION_MANAGER,
|
|
/// device/endpoint is a FLOATS Receiver
|
|
FLOATS_RECEIVER,
|
|
/// device/endpoint is a display
|
|
DISPLAY,
|
|
/// device/endpoint is a history server
|
|
HISTORY_SERVER,
|
|
/// device/endpoint is a threat consolidation application
|
|
THREAT_CONSOLIDATION,
|
|
/// device/endpoint is an own track generator
|
|
OWN_TRACK_GENERATOR,
|
|
/// device/endpoint is a data fusion application
|
|
DATA_FUSION,
|
|
/// device/endpoint is an identification process application
|
|
ID_PROCESS,
|
|
/// device/endpoint type is unknown
|
|
UNKNOWN
|
|
};
|
|
|
|
/**
|
|
* @brief map converting from BC::DataTypes::deviceMajorType to string
|
|
*/
|
|
static std::map<BC::DataTypes::deviceMajorType, std::string>deviceMojorTypeMap =
|
|
{
|
|
{BC::DataTypes::deviceMajorType::UNKNOWN, "Unknown"},
|
|
{BC::DataTypes::deviceMajorType::DATA_FUSION, "Data Fusion"},
|
|
{BC::DataTypes::deviceMajorType::CAMERA, "Camera"},
|
|
{BC::DataTypes::deviceMajorType::DISPLAY, "Display"},
|
|
{BC::DataTypes::deviceMajorType::FLOATS_RECEIVER, "FLOATS Receiver"},
|
|
{BC::DataTypes::deviceMajorType::HISTORY_SERVER, "History Server"},
|
|
{BC::DataTypes::deviceMajorType::ID_PROCESS, "Identification Process"},
|
|
{BC::DataTypes::deviceMajorType::LIDAR, "Lidar"},
|
|
{BC::DataTypes::deviceMajorType::OWN_TRACK_GENERATOR, "Own Track Generator"},
|
|
{BC::DataTypes::deviceMajorType::RADAR, "Radar"},
|
|
{BC::DataTypes::deviceMajorType::SONAR, "Sonar"},
|
|
{BC::DataTypes::deviceMajorType::THREAT_EVALUATION_MANAGER, "Threat Evaluation"},
|
|
{BC::DataTypes::deviceMajorType::THREAT_CONSOLIDATION, "Threat Consolidation"}
|
|
};
|
|
|
|
} // namespace DataTypes
|
|
|
|
|
|
/**
|
|
* @brief function to get the current time in every BC implementation
|
|
*/
|
|
inline BC::DataTypes::BCTimeType getCurrentTime()
|
|
{
|
|
std::chrono::time_point<BC::DataTypes::BCClockType> now = BC::DataTypes::BCClockType::now();
|
|
|
|
return std::chrono::duration_cast<BC::DataTypes::BCPeriod>(now.time_since_epoch()).count();
|
|
}
|
|
|
|
/**
|
|
* @brief Class/Namespace for BC related constants
|
|
*/
|
|
class Constants
|
|
{
|
|
public:
|
|
|
|
/// the epoch starting date used throughout BC, used to abstract from the epoch used
|
|
/// in different operating systems and standards
|
|
static constexpr const char *cEpochDateTime = "1970-01-01 00:00";
|
|
|
|
///@name constants related to devices
|
|
///@{
|
|
|
|
/// constants identifying that we want to select/address all devices in the CMS, required for publish/subscribe
|
|
static const BC::DataTypes::deviceIdType allDevices = 0;
|
|
|
|
///@}
|
|
|
|
|
|
///@name PubSub Domain related constants
|
|
///@{
|
|
|
|
/// constant identifying the real world domain
|
|
static constexpr const char *cRealWorldDomain = "REALWORLD";
|
|
|
|
/// constant identifying the default simulation domain
|
|
static constexpr const char *cSimWorldDomain = "SIMULATION";
|
|
|
|
/// constant identifying the Management domain
|
|
static constexpr const char *cManagementDomain = "_MANAGEMENT_";
|
|
|
|
/// constant identifying all domains
|
|
static constexpr const char *cAllDomains = "_DOMAIN_ALL_";
|
|
|
|
///@}
|
|
|
|
///@name PubSub Topic related constants
|
|
///@{
|
|
|
|
/// constant identifying that the subscriber is interested in all topics
|
|
static constexpr const char *cAllTopics = "_TOPIC_ALL_";
|
|
|
|
/// constant identifying the PING topic, for pinging subscribers
|
|
static constexpr const char *cPingTopic = "_TOPIC_PING_";
|
|
|
|
/// constant identifying the PONG topic, for answering a PING
|
|
static constexpr const char *cPongTopic = "_TOPIC_PONG_";
|
|
|
|
/// constant identifying the HOTPLUG JOIN message topic
|
|
static constexpr const char *cHotplugJoin = "_HOTPLUG_JOIN_";
|
|
|
|
/// constant identifying the HOTPLUG LEAVE message topic
|
|
static constexpr const char *cHotplugLeave = "_HOTPLUG_LEAVE_";
|
|
|
|
/// constant identifying the PING message topic
|
|
static constexpr const char *cPing = "_PING_";
|
|
|
|
/// constant identifying the PONG message topic
|
|
static constexpr const char *cPong = "_PONG_";
|
|
};
|
|
|
|
} // namespace BC
|
|
|