523 lines
14 KiB
C
523 lines
14 KiB
C
|
/**
|
||
|
* telephony.h
|
||
|
* This file is part of the YATE Project http://YATE.null.ro
|
||
|
*/
|
||
|
#ifndef __TELEPHONY_H
|
||
|
#define __TELEPHONY_H
|
||
|
|
||
|
#ifndef __cplusplus
|
||
|
#error C++ is required
|
||
|
#endif
|
||
|
|
||
|
#include <telengine.h>
|
||
|
|
||
|
/**
|
||
|
* Holds all Telephony Engine related classes.
|
||
|
*/
|
||
|
namespace TelEngine {
|
||
|
|
||
|
/**
|
||
|
* The DataBlock holds a data buffer with no specific formatting.
|
||
|
* @short A class that holds just a block of raw data
|
||
|
*/
|
||
|
class DataBlock : public GenObject
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
/**
|
||
|
* Constructs an empty data block
|
||
|
*/
|
||
|
DataBlock();
|
||
|
|
||
|
/**
|
||
|
* Copy constructor
|
||
|
*/
|
||
|
DataBlock(const DataBlock &value);
|
||
|
|
||
|
/**
|
||
|
* Constructs an initialized data block
|
||
|
* @param value Data to assign, may be NULL to fill with zeros
|
||
|
* @param len Length of data, may be zero (then @ref value is ignored)
|
||
|
* @param copyData True to make a copy of the data, false to just insert the pointer
|
||
|
*/
|
||
|
DataBlock(void *value, unsigned int len, bool copyData = true);
|
||
|
|
||
|
/**
|
||
|
* Destroys the data, disposes the memory.
|
||
|
*/
|
||
|
virtual ~DataBlock();
|
||
|
|
||
|
/**
|
||
|
* Get a pointer to the stored data.
|
||
|
* @return A pointer to the data or NULL.
|
||
|
*/
|
||
|
inline void *data() const
|
||
|
{ return m_data; }
|
||
|
|
||
|
/**
|
||
|
* Checks if the block holds a NULL pointer.
|
||
|
* @return True if the block holds NULL, false otherwise.
|
||
|
*/
|
||
|
inline bool null() const
|
||
|
{ return !m_data; }
|
||
|
|
||
|
/**
|
||
|
* Get the length of the stored data.
|
||
|
* @return The length of the stored data, zero for NULL.
|
||
|
*/
|
||
|
inline unsigned int length() const
|
||
|
{ return m_length; }
|
||
|
|
||
|
/**
|
||
|
* Clear the data and optionally free the memory
|
||
|
* @param deleteData True to free the deta block, false to just forget it
|
||
|
*/
|
||
|
void clear(bool deleteData = true);
|
||
|
|
||
|
/**
|
||
|
* Assign data to the object
|
||
|
* @param value Data to assign, may be NULL to fill with zeros
|
||
|
* @param len Length of data, may be zero (then @ref value is ignored)
|
||
|
* @param copyData True to make a copy of the data, false to just insert the pointer
|
||
|
*/
|
||
|
DataBlock& assign(void *value, unsigned int len, bool copyData = true);
|
||
|
|
||
|
/**
|
||
|
* Append data to the current block
|
||
|
* @param value Data to append
|
||
|
*/
|
||
|
void append(const DataBlock &value);
|
||
|
|
||
|
/**
|
||
|
* Insert data before the current block
|
||
|
* @param value Data to insert
|
||
|
*/
|
||
|
void insert(const DataBlock &value);
|
||
|
|
||
|
/**
|
||
|
* Truncate the data block
|
||
|
* @param len The maximum length to keep
|
||
|
*/
|
||
|
void truncate(unsigned int len);
|
||
|
|
||
|
/**
|
||
|
* Cut off a number of bytes from the data block
|
||
|
* @param len Amount to cut, positive to cut from end, negative to cut from start of block
|
||
|
*/
|
||
|
void cut(int len);
|
||
|
|
||
|
/**
|
||
|
* Assignment operator.
|
||
|
*/
|
||
|
DataBlock& operator=(const DataBlock &value);
|
||
|
|
||
|
/**
|
||
|
* Appending operator.
|
||
|
*/
|
||
|
inline DataBlock& operator+=(const DataBlock &value)
|
||
|
{ append(value); return *this; }
|
||
|
|
||
|
/**
|
||
|
* Convert data from a different format
|
||
|
* @param src Source data block
|
||
|
* @param sFormat Name of the source format
|
||
|
* @param dFormat Name of the destination format
|
||
|
* @param maxlen Maximum amount to convert, 0 to use source
|
||
|
* @return True if converted successfully, false on failure
|
||
|
*/
|
||
|
bool convert(const DataBlock &src, const String &sFormat,
|
||
|
const String &dFormat, unsigned maxlen = 0);
|
||
|
|
||
|
private:
|
||
|
void *m_data;
|
||
|
unsigned int m_length;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* A generic data handling object
|
||
|
*/
|
||
|
class DataNode : public RefObject
|
||
|
{
|
||
|
public:
|
||
|
/**
|
||
|
* Construct a DataNode
|
||
|
* @param format Name of the data format, default none
|
||
|
*/
|
||
|
DataNode(const char *format = 0)
|
||
|
: m_format(format) { }
|
||
|
|
||
|
/**
|
||
|
* Get the computing cost of converting the data to the format asked
|
||
|
* @param format Name of the format to check for
|
||
|
* @return -1 if unsupported, 0 for native format else cost in KIPS
|
||
|
*/
|
||
|
virtual int costFormat(const String &format)
|
||
|
{ return -1; }
|
||
|
|
||
|
/**
|
||
|
* Change the format used to transfer data
|
||
|
* @param format Name of the format to set for data
|
||
|
* @return True if the format changed successfully, false if not changed
|
||
|
*/
|
||
|
virtual bool setFormat(const String &format)
|
||
|
{ return false; }
|
||
|
|
||
|
/**
|
||
|
* Get the name of the format currently in use
|
||
|
* @return Name of the data format
|
||
|
*/
|
||
|
inline const String &getFormat() const
|
||
|
{ return m_format; }
|
||
|
|
||
|
protected:
|
||
|
/**
|
||
|
* The name of the data format the node is currently using
|
||
|
*/
|
||
|
String m_format;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* A data consumer
|
||
|
*/
|
||
|
class DataConsumer : public DataNode
|
||
|
{
|
||
|
friend class DataSource;
|
||
|
public:
|
||
|
/**
|
||
|
* Consumer constructor
|
||
|
* @param format Name of the data format, default "slin" (Signed Linear)
|
||
|
*/
|
||
|
DataConsumer(const char *format = "slin")
|
||
|
: DataNode(format), m_source(0) { }
|
||
|
|
||
|
/**
|
||
|
* Consumes the data sent to it from a source
|
||
|
* @param data The raw data block to process; an empty block ends data
|
||
|
*/
|
||
|
virtual void Consume(const DataBlock &data) = 0;
|
||
|
|
||
|
/**
|
||
|
* Get the data source of this object if it's connected
|
||
|
* @return A pointer to the DataSource object or NULL
|
||
|
*/
|
||
|
DataSource *getConnSource() const
|
||
|
{ return m_source; }
|
||
|
|
||
|
/**
|
||
|
* Get the data source of a translator object
|
||
|
* @return A pointer to the DataSource object or NULL
|
||
|
*/
|
||
|
virtual DataSource *getTransSource() const
|
||
|
{ return 0; }
|
||
|
|
||
|
private:
|
||
|
inline void setSource(DataSource *source)
|
||
|
{ m_source = source; }
|
||
|
DataSource *m_source;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* A data source
|
||
|
*/
|
||
|
class DataSource : public DataNode
|
||
|
{
|
||
|
friend class DataTranslator;
|
||
|
public:
|
||
|
/**
|
||
|
* Source constructor
|
||
|
* @param format Name of the data format, default "slin" (Signed Linear)
|
||
|
*/
|
||
|
DataSource(const char *format = "slin")
|
||
|
: DataNode(format), m_translator(0) { }
|
||
|
|
||
|
/**
|
||
|
* Forwards the data to its consumers
|
||
|
* @param data The raw data block to forward; an empty block ends data
|
||
|
*/
|
||
|
void Forward(const DataBlock &data);
|
||
|
|
||
|
/**
|
||
|
* Attach a data consumer
|
||
|
* @param consumer Data consumer to attach
|
||
|
* @return True on success, false on failure
|
||
|
*/
|
||
|
bool attach(DataConsumer *consumer);
|
||
|
|
||
|
/**
|
||
|
* Detach a data consumer
|
||
|
* @param consumer Data consumer to detach
|
||
|
* @return True on success, false on failure
|
||
|
*/
|
||
|
bool detach(DataConsumer *consumer);
|
||
|
|
||
|
/**
|
||
|
* Detach all data consumers
|
||
|
*/
|
||
|
inline void clear()
|
||
|
{ m_consumers.clear(); }
|
||
|
|
||
|
/**
|
||
|
* Get the master translator object if this source is part of a translator
|
||
|
* @return A pointer to the DataTranslator object or NULL
|
||
|
*/
|
||
|
DataTranslator *getTranslator() const
|
||
|
{ return m_translator; }
|
||
|
|
||
|
protected:
|
||
|
inline void setTranslator(DataTranslator *translator)
|
||
|
{ m_translator = translator; }
|
||
|
DataTranslator *m_translator;
|
||
|
ObjList m_consumers;
|
||
|
Mutex m_mutex;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* A data source with a thread of its own
|
||
|
*/
|
||
|
class ThreadedSource : public DataSource
|
||
|
{
|
||
|
friend class ThreadedSourcePrivate;
|
||
|
public:
|
||
|
/**
|
||
|
* The destructor, stops the thread
|
||
|
*/
|
||
|
virtual ~ThreadedSource();
|
||
|
|
||
|
/**
|
||
|
* Start the worker thread
|
||
|
*/
|
||
|
void start(const char *name = "ThreadedSource");
|
||
|
|
||
|
protected:
|
||
|
/**
|
||
|
* Threaded Source constructor
|
||
|
* @param format Name of the data format, default "slin" (Signed Linear)
|
||
|
*/
|
||
|
ThreadedSource(const char *format = "slin")
|
||
|
: DataSource(format), m_thread(0) { }
|
||
|
|
||
|
/**
|
||
|
* The worker method. You have to reimplement it as you need
|
||
|
*/
|
||
|
virtual void run() = 0;
|
||
|
|
||
|
/**
|
||
|
* The cleanup after thread method
|
||
|
*/
|
||
|
virtual void cleanup();
|
||
|
|
||
|
private:
|
||
|
ThreadedSourcePrivate *m_thread;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* The DataEndpoint holds an endpoint capable of performing unidirectional
|
||
|
* or bidirectional data transfers
|
||
|
* @short A data transfer endpoint capable of sending and/or receiving data
|
||
|
*/
|
||
|
class DataEndpoint : public RefObject
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
/**
|
||
|
* Creates am empty data ednpoint
|
||
|
*/
|
||
|
inline DataEndpoint(const char *name = 0)
|
||
|
: m_name(name), m_source(0), m_consumer(0), m_peer(0) { }
|
||
|
|
||
|
/**
|
||
|
* Destroys the endpoint, source and consumer
|
||
|
*/
|
||
|
~DataEndpoint();
|
||
|
|
||
|
/**
|
||
|
* Connect the source and consumer of the endpoint to a peer
|
||
|
* @param peer Pointer to the peer data endpoint
|
||
|
* @return True if connected, false if incompatible source/consumer
|
||
|
*/
|
||
|
bool connect(DataEndpoint *peer);
|
||
|
|
||
|
/**
|
||
|
* Disconnect from the connected endpoint
|
||
|
*/
|
||
|
void disconnect();
|
||
|
|
||
|
/**
|
||
|
* Set the data source of this object
|
||
|
* @param source A pointer to the new source or NULL
|
||
|
*/
|
||
|
void setSource(DataSource *source = 0);
|
||
|
|
||
|
/**
|
||
|
* Get the data source of this object
|
||
|
* @return A pointer to the DataSource object or NULL
|
||
|
*/
|
||
|
DataSource *getSource() const
|
||
|
{ return m_source; }
|
||
|
|
||
|
/**
|
||
|
* Set the data consumer of this object
|
||
|
* @param consumer A pointer to the new consumer or NULL
|
||
|
*/
|
||
|
void setConsumer(DataConsumer *consumer = 0);
|
||
|
|
||
|
/**
|
||
|
* Get the data consumer of this object
|
||
|
* @return A pointer to the DataConsumer object or NULL
|
||
|
*/
|
||
|
DataConsumer *getConsumer() const
|
||
|
{ return m_consumer; }
|
||
|
|
||
|
/*
|
||
|
* Get a pointer to the peer endpoint
|
||
|
* @return A pointer to the peer endpoint or NULL
|
||
|
*/
|
||
|
inline DataEndpoint *getPeer() const
|
||
|
{ return m_peer; }
|
||
|
|
||
|
/**
|
||
|
* Get the name set in constructor
|
||
|
* @return A reference to the name as hashed string
|
||
|
*/
|
||
|
inline const String &name() const
|
||
|
{ return m_name; }
|
||
|
|
||
|
protected:
|
||
|
/**
|
||
|
* Connect notification method
|
||
|
*/
|
||
|
virtual void connected() { }
|
||
|
|
||
|
/**
|
||
|
* Disconnect notification method
|
||
|
*/
|
||
|
virtual void disconnected() { }
|
||
|
|
||
|
/**
|
||
|
* Attempt to connect the endpoint to a peer of the same type
|
||
|
* @param peer Pointer to the endpoint data driver
|
||
|
* @return True if connected, false if failed native connection
|
||
|
*/
|
||
|
virtual bool nativeConnect(DataEndpoint *peer)
|
||
|
{ return false; }
|
||
|
|
||
|
/*
|
||
|
* Set the peer endpoint pointer
|
||
|
* @param peer A pointer to the new peer or NULL
|
||
|
*/
|
||
|
void setPeer(DataEndpoint *peer);
|
||
|
|
||
|
private:
|
||
|
String m_name;
|
||
|
DataSource *m_source;
|
||
|
DataConsumer *m_consumer;
|
||
|
DataEndpoint *m_peer;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* The DataTranslator holds a translator (codec) capable of unidirectional
|
||
|
* conversion of data from one type to another
|
||
|
* @short An unidirectional data translator (codec)
|
||
|
*/
|
||
|
class DataTranslator : public DataConsumer
|
||
|
{
|
||
|
friend class TranslatorFactory;
|
||
|
public:
|
||
|
/**
|
||
|
* Construct a data translator
|
||
|
* @param sFormat Name of the source format (data received from the consumer)
|
||
|
* @param dFormat Name of the destination format (data supplied to the source)
|
||
|
*/
|
||
|
DataTranslator(const char *sFormat, const char *dFormat);
|
||
|
|
||
|
/**
|
||
|
* Creates a data translator from an existing source
|
||
|
* does not increment the source's reference counter
|
||
|
* @param sFormat Name of the source format (data received from the consumer)
|
||
|
* @param source Optional pointer to a DataSource object
|
||
|
*/
|
||
|
DataTranslator(const char *sFormat, DataSource *source = 0);
|
||
|
|
||
|
/**
|
||
|
* Destroys the translator and its source
|
||
|
*/
|
||
|
~DataTranslator();
|
||
|
|
||
|
/**
|
||
|
* Get the data source of a translator object
|
||
|
* @return A pointer to the DataSource object or NULL
|
||
|
*/
|
||
|
virtual DataSource *getTransSource() const
|
||
|
{ return m_tsource; }
|
||
|
|
||
|
/**
|
||
|
* Creates a translator given the source and destination format names
|
||
|
* @param sFormat Name of the source format (data received from the consumer)
|
||
|
* @param dFormat Name of the destination format (data supplied to the source)
|
||
|
* @return A pointer to a DataTranslator object or NULL if no known codec exists
|
||
|
*/
|
||
|
static DataTranslator *create(const String &sFormat, const String &dFormat);
|
||
|
|
||
|
/**
|
||
|
* Attach a consumer to a source, possibly trough a chain of translators
|
||
|
* @param source Source to attach the chain to
|
||
|
* @param consumer Consumer where the chain ends
|
||
|
* @return True if successfull, false if no translator chain could be built
|
||
|
*/
|
||
|
static bool attachChain(DataSource *source, DataConsumer *consumer);
|
||
|
|
||
|
/**
|
||
|
* Detach a consumer from a source, possibly trough a chain of translators
|
||
|
* @param source Source to dettach the chain from
|
||
|
* @param consumer Consumer where the chain ends
|
||
|
* @return True if successfull, false if source and consumers were not attached
|
||
|
*/
|
||
|
static bool detachChain(DataSource *source, DataConsumer *consumer);
|
||
|
|
||
|
protected:
|
||
|
/**
|
||
|
* Install a Translator Factory in the list of known codecs
|
||
|
* @param factory A pointer to a TranslatorFactory instance
|
||
|
*/
|
||
|
static void install(TranslatorFactory *factory);
|
||
|
|
||
|
/**
|
||
|
* Remove a Translator Factory from the list of known codecs
|
||
|
* @param factory A pointer to a TranslatorFactory instance
|
||
|
*/
|
||
|
static void uninstall(TranslatorFactory *factory);
|
||
|
|
||
|
private:
|
||
|
DataTranslator(); // No default constructor please
|
||
|
DataSource *m_tsource;
|
||
|
static Mutex s_mutex;
|
||
|
static ObjList s_factories;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* A factory for constructing data translators by format name
|
||
|
* conversion of data from one type to another
|
||
|
* @short An unidirectional data translator (codec)
|
||
|
*/
|
||
|
class TranslatorFactory : public GenObject
|
||
|
{
|
||
|
public:
|
||
|
TranslatorFactory()
|
||
|
{ DataTranslator::install(this); }
|
||
|
|
||
|
virtual ~TranslatorFactory()
|
||
|
{ DataTranslator::uninstall(this); }
|
||
|
|
||
|
/**
|
||
|
* Creates a translator given the source and destination format names
|
||
|
* @param sFormat Name of the source format (data received from the consumer)
|
||
|
* @param dFormat Name of the destination format (data supplied to the source)
|
||
|
* @return A pointer to a DataTranslator object or NULL
|
||
|
*/
|
||
|
virtual DataTranslator *create(const String &sFormat, const String &dFormat) = 0;
|
||
|
};
|
||
|
|
||
|
}; // namespace TelEngine
|
||
|
|
||
|
#endif /* __TELEPHONY_H */
|