/*
Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Her Majesty the Queen in
Right of Canada (Communications Research Center Canada)
Copyright (C) 2013 Matthias P. Braendli
http://mpb.li
An object-oriented version of the output channels.
*/
/*
This file is part of CRC-DabMux.
CRC-DabMux is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
CRC-DabMux is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with CRC-DabMux. If not, see .
*/
#ifndef __DAB_OUTPUT_H
#define __DAB_OUTPUT_H
#include "UdpSocket.h"
#include "TcpServer.h"
#include "TcpLog.h"
#include
#include
#ifdef _WIN32
# include
# ifdef __MINGW32__
# define FS_DECLARE_CFG_ARRAYS
# include
# endif
# include
#else
# include
# include
# ifndef O_BINARY
# define O_BINARY 0
# endif // O_BINARY
#endif
#ifdef HAVE_OUTPUT_ZEROMQ
# include "zmq.hpp"
#endif
extern TcpLog etiLog;
// Abstract base class for all outputs
class DabOutput
{
public:
virtual int Open(const char* name) = 0;
int Open(std::string name)
{
return Open(name.c_str());
}
virtual int Write(void* buffer, int size) = 0;
virtual int Close() = 0;
virtual ~DabOutput() {};
};
// ----- used in File and Fifo outputs
enum EtiFileType {
ETI_FILE_TYPE_NONE = 0,
ETI_FILE_TYPE_RAW,
ETI_FILE_TYPE_STREAMED,
ETI_FILE_TYPE_FRAMED
};
// ---------- File output ------------
class DabOutputFile : public DabOutput
{
public:
DabOutputFile() {
nbFrames_ = 0;
file_ = -1;
type_ = ETI_FILE_TYPE_FRAMED;
}
DabOutputFile(const DabOutputFile& other)
{
file_ = other.file_;
nbFrames_ = other.nbFrames_;
type_ = other.type_;
}
~DabOutputFile() {}
int Open(const char* filename);
int Write(void* buffer, int size);
int Close();
protected:
int file_;
EtiFileType type_;
unsigned long nbFrames_;
};
// ---------- FIFO output ------------
// only write is different for the FIFO output
class DabOutputFifo : public DabOutputFile
{
public:
DabOutputFifo() : DabOutputFile() {}
~DabOutputFifo() {}
int Write(void* buffer, int size);
};
// -------------- RAW socket -----------
class DabOutputRaw : public DabOutput
{
public:
DabOutputRaw()
{
#ifdef _WIN32
socket_ = INVALID_HANDLE_VALUE;
#else
socket_ = -1;
isCyclades_ = false;
#endif
buffer_ = new unsigned char[6144];
}
DabOutputRaw(const DabOutputRaw& other)
{
socket_ = other.socket_;
#ifndef _WIN32
isCyclades_ = other.isCyclades_;
#endif
buffer_ = other.buffer_;
}
~DabOutputRaw() {
delete[] buffer_;
}
int Open(const char* name);
int Write(void* buffer, int size);
int Close();
private:
#ifdef _WIN32
HANDLE socket_;
#else
int socket_;
bool isCyclades_;
#endif
unsigned char* buffer_;
};
// -------------- UDP ------------------
class DabOutputUdp : public DabOutput
{
public:
DabOutputUdp() {
UdpSocket::init();
packet_ = new UdpPacket(6144);
socket_ = new UdpSocket();
}
DabOutputUdp(const DabOutputUdp& other)
{
packet_ = other.packet_;
socket_ = other.socket_;
}
~DabOutputUdp() {
delete socket_;
delete packet_;
}
int Open(const char* name);
int Write(void* buffer, int size);
int Close() { return 0; }
private:
UdpSocket* socket_;
UdpPacket* packet_;
};
// -------------- TCP ------------------
class DabOutputTcp : public DabOutput
{
public:
DabOutputTcp()
{
TcpSocket::init();
server = new TcpServer();
client = NULL;
}
DabOutputTcp(const DabOutputTcp& other)
{
server = other.server;
client = other.client;
thread_ = other.thread_;
}
~DabOutputTcp() {
#ifdef _WIN32
CloseHandle(this->thread_);
#endif
delete this->server;
delete this->client;
}
int Open(const char* name);
int Write(void* buffer, int size);
int Close();
TcpServer* server;
TcpSocket* client;
private:
pthread_t thread_;
};
// -------------- Simul ------------------
class DabOutputSimul : public DabOutput
{
public:
DabOutputSimul() {}
DabOutputSimul(const DabOutputSimul& other)
{
startTime_ = other.startTime_;
}
~DabOutputSimul() { }
int Open(const char* name);
int Write(void* buffer, int size);
int Close() { return 0; }
private:
#ifdef _WIN32
DWORD startTime_;
#else
timeval startTime_;
#endif
};
#if defined(HAVE_OUTPUT_ZEROMQ)
// -------------- ZeroMQ message queue ------------------
class DabOutputZMQ : public DabOutput
{
public:
DabOutputZMQ() :
zmq_proto_(""), zmq_context_(1), zmq_pub_sock_(zmq_context_, ZMQ_PUB)
{
throw std::runtime_error("ERROR: No ZMQ protocol specified !");
}
DabOutputZMQ(std::string zmq_proto) :
zmq_proto_(zmq_proto), zmq_context_(1), zmq_pub_sock_(zmq_context_, ZMQ_PUB)
{ }
DabOutputZMQ(const DabOutputZMQ& other) :
zmq_proto_(other.zmq_proto_), zmq_context_(1), zmq_pub_sock_(zmq_context_, ZMQ_PUB)
{
// cannot copy context
}
~DabOutputZMQ()
{
zmq_pub_sock_.close();
}
int Open(const char* name);
int Write(void* buffer, int size);
int Close();
private:
std::string zmq_proto_;
zmq::context_t zmq_context_; // handle for the zmq context
zmq::socket_t zmq_pub_sock_; // handle for the zmq publisher socket
};
#endif
#endif