cpp/frameReceiver/include/FrameReceiverConfig.h
/*!
* FrameReceiverConfig.h - FrameReceiver configuration class
*
* This class implements a simple storage container for FrameReceiver
* configuration parameters derived from command-line options and file
* parsing.
*
* Created on: Feb 4, 2015
* Author: Tim Nicholls, STFC Application Engineering Group
*/
#ifndef FRAMERECEIVERCONFIG_H_
#define FRAMERECEIVERCONFIG_H_
#include <map>
#include <vector>
#include <iostream>
#include <boost/scoped_ptr.hpp>
#include "FrameReceiverDefaults.h"
#include "OdinDataDefaults.h"
#include "IpcMessage.h"
using namespace OdinData;
namespace FrameReceiver
{
const std::string CONFIG_MAX_BUFFER_MEM = "max_buffer_mem";
const std::string CONFIG_DECODER_PATH = "decoder_path";
const std::string CONFIG_DECODER_TYPE = "decoder_type";
const std::string CONFIG_DECODER_CONFIG = "decoder_config";
const std::string CONFIG_RX_TYPE = "rx_type";
const std::string CONFIG_CTRL_ENDPOINT = "ctrl_endpoint";
const std::string CONFIG_RX_ENDPOINT = "rx_endpoint";
const std::string CONFIG_FRAME_READY_ENDPOINT = "frame_ready_endpoint";
const std::string CONFIG_FRAME_RELEASE_ENDPOINT = "frame_release_endpoint";
const std::string CONFIG_RX_PORTS = "rx_ports";
const std::string CONFIG_RX_ADDRESS = "rx_address";
const std::string CONFIG_RX_RECV_BUFFER_SIZE = "rx_recv_buffer_size";
const std::string CONFIG_SHARED_BUFFER_NAME = "shared_buffer_name";
const std::string CONFIG_FRAME_TIMEOUT_MS = "frame_timeout_ms";
const std::string CONFIG_FRAME_COUNT = "frame_count";
const std::string CONFIG_ENABLE_PACKET_LOGGING = "enable_packet_logging";
const std::string CONFIG_FORCE_RECONFIG = "force_reconfig";
const std::string CONFIG_DEBUG = "debug_level";
const std::string CONFIG_FRAMES = "frames";
class FrameReceiverConfig
{
public:
FrameReceiverConfig() :
max_buffer_mem_(Defaults::default_max_buffer_mem),
decoder_path_(Defaults::default_decoder_path),
decoder_type_(Defaults::default_decoder_type),
decoder_config_(new IpcMessage()),
rx_type_(Defaults::default_rx_type),
rx_address_(Defaults::default_rx_address),
rx_recv_buffer_size_(Defaults::default_rx_recv_buffer_size),
rx_channel_endpoint_(""),
ctrl_channel_endpoint_(""),
frame_ready_endpoint_(""),
frame_release_endpoint_(""),
shared_buffer_name_(OdinData::Defaults::default_shared_buffer_name),
frame_timeout_ms_(Defaults::default_frame_timeout_ms),
enable_packet_logging_(Defaults::default_enable_packet_logging),
force_reconfig_(Defaults::default_force_reconfig)
{
tokenize_port_list(rx_ports_, Defaults::default_rx_port_list);
};
void tokenize_port_list(std::vector<uint16_t>& port_list, const std::string port_list_str)
{
port_list.clear();
const std::string delimiter(",");
std::size_t start = 0, end = 0;
while ( end != std::string::npos)
{
end = port_list_str.find(delimiter, start);
const char* port_str = port_list_str.substr(start, (end == std::string::npos) ? std::string::npos : end - start).c_str();
start = ((end > (std::string::npos - delimiter.size())) ? std::string::npos : end + delimiter.size());
uint16_t port = static_cast<uint16_t>(strtol(port_str, NULL, 0));
if (port != 0)
{
port_list.push_back( port );
}
}
}
static Defaults::RxType map_rx_name_to_type(std::string& rx_name)
{
Defaults::RxType rx_type = Defaults::RxTypeIllegal;
static std::map<std::string, Defaults::RxType> rx_name_map;
if (rx_name_map.empty()){
rx_name_map["udp"] = Defaults::RxTypeUDP;
rx_name_map["UDP"] = Defaults::RxTypeUDP;
rx_name_map["zmq"] = Defaults::RxTypeZMQ;
rx_name_map["ZMQ"] = Defaults::RxTypeZMQ;
rx_name_map["tcp"] = Defaults::RxTypeTCP;
rx_name_map["TCP"] = Defaults::RxTypeTCP;
}
if (rx_name_map.count(rx_name)){
rx_type = rx_name_map[rx_name];
}
return rx_type;
}
static std::string map_rx_type_to_name(Defaults::RxType rx_type)
{
std::string rx_name;
static std::map<Defaults::RxType, std::string> rx_type_map;
if (rx_type_map.empty())
{
rx_type_map[Defaults::RxTypeUDP] = "udp";
rx_type_map[Defaults::RxTypeZMQ] = "zmq";
rx_type_map[Defaults::RxTypeTCP] = "tcp";
rx_type_map[Defaults::RxTypeIllegal] = "unknown";
}
if (rx_type_map.count(rx_type))
{
rx_name = rx_type_map[rx_type];
}
else
{
rx_name = rx_type_map[Defaults::RxTypeIllegal];
}
return rx_name;
}
std::string rx_port_list(void)
{
std::stringstream rx_ports_stream;
std::copy(rx_ports_.begin(), rx_ports_.end(),
std::ostream_iterator<uint16_t>(rx_ports_stream, ","));
std::string rx_port_list = rx_ports_stream.str();
rx_port_list.erase(rx_port_list.length()-1);
return rx_port_list;
}
void as_ipc_message(OdinData::IpcMessage& config_msg)
{
config_msg.set_msg_type(OdinData::IpcMessage::MsgTypeCmd);
config_msg.set_msg_val(OdinData::IpcMessage::MsgValCmdConfigure);
config_msg.set_param<std::size_t>(CONFIG_MAX_BUFFER_MEM, max_buffer_mem_);
config_msg.set_param<std::string>(CONFIG_DECODER_PATH, decoder_path_);
config_msg.set_param<std::string>(CONFIG_DECODER_TYPE, decoder_type_);
config_msg.set_param<std::string>(CONFIG_RX_TYPE, this->map_rx_type_to_name(rx_type_));
config_msg.set_param<std::string>(CONFIG_RX_PORTS, rx_port_list());
config_msg.set_param<std::string>(CONFIG_RX_ADDRESS, rx_address_);
config_msg.set_param<int>(CONFIG_RX_RECV_BUFFER_SIZE, rx_recv_buffer_size_);
config_msg.set_param<std::string>(CONFIG_RX_ENDPOINT, rx_channel_endpoint_);
config_msg.set_param<std::string>(CONFIG_CTRL_ENDPOINT, ctrl_channel_endpoint_);
config_msg.set_param<std::string>(CONFIG_FRAME_READY_ENDPOINT, frame_ready_endpoint_);
config_msg.set_param<std::string>(CONFIG_FRAME_RELEASE_ENDPOINT, frame_release_endpoint_);
config_msg.set_param<std::string>(CONFIG_SHARED_BUFFER_NAME, shared_buffer_name_);
config_msg.set_param<int>(CONFIG_FRAME_COUNT, frame_count_);
std::string decoder_config_path("decoder_config/");
config_msg.set_param<int>(decoder_config_path + CONFIG_FRAME_TIMEOUT_MS, frame_timeout_ms_);
config_msg.set_param<bool>(decoder_config_path + CONFIG_ENABLE_PACKET_LOGGING,
enable_packet_logging_);
config_msg.set_param<bool>(CONFIG_FORCE_RECONFIG, force_reconfig_);
}
private:
std::size_t max_buffer_mem_; //!< Amount of shared buffer memory to allocate for frame buffers
std::string decoder_path_; //!< Path to decoder library
std::string decoder_type_; //!< Decoder type receiving data for - drives frame size
boost::scoped_ptr<IpcMessage> decoder_config_; //!< Decoder configuration data as IpcMessage
Defaults::RxType rx_type_; //!< Type of receiver interface (UDP or ZMQ)
std::vector<uint16_t> rx_ports_; //!< Port(s) to receive frame data on
std::string rx_address_; //!< IP address to receive frame data on
int rx_recv_buffer_size_; //!< Receive socket buffer size
unsigned int io_threads_; //!< Number of IO threads for IPC channels
std::string rx_channel_endpoint_; //!< IPC channel endpoint for RX thread communication
std::string ctrl_channel_endpoint_; //!< IPC channel endpoint for control communication with other processes
std::string frame_ready_endpoint_; //!< IPC channel endpoint for transmitting frame ready notifications to other processes
std::string frame_release_endpoint_; //!< IPC channel endpoint for receiving frame release notifications from other processes
std::string shared_buffer_name_; //!< Shared memory frame buffer name
unsigned int frame_timeout_ms_; //!< Incomplete frame timeout in milliseconds
unsigned int frame_count_; //!< Number of frames to receive before terminating
bool enable_packet_logging_; //!< Enable packet diagnostic logging
bool force_reconfig_; //!< Force a comlete reconfigure of the frame receiver
friend class FrameReceiverApp;
friend class FrameReceiverController;
friend class FrameReceiverRxThread;
friend class FrameReceiverUDPRxThread;
friend class FrameReceiverZMQRxThread;
friend class FrameReceiverTCPRxThread;
friend class FrameReceiverConfigTestProxy;
friend class FrameReceiverRxThreadTestProxy;
};
} // namespace FrameReceiver
#endif /* FRAMERECEIVERCONFIG_H_ */