2318 lines
71 KiB
C++
2318 lines
71 KiB
C++
/**
|
|
* yateiax.h
|
|
* Yet Another IAX2 Stack
|
|
* This file is part of the YATE Project http://YATE.null.ro
|
|
*
|
|
* Yet Another Telephony Engine - a fully featured software PBX and IVR
|
|
* Copyright (C) 2004-2006 Null Team
|
|
*
|
|
* This program 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 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program 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 this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#ifndef __YATEIAX_H
|
|
#define __YATEIAX_H
|
|
|
|
#include <yateclass.h>
|
|
|
|
#ifdef _WINDOWS
|
|
|
|
#ifdef LIBYIAX_EXPORTS
|
|
#define YIAX_API __declspec(dllexport)
|
|
#else
|
|
#ifndef LIBYIAX_STATIC
|
|
#define YIAX_API __declspec(dllimport)
|
|
#endif
|
|
#endif
|
|
|
|
#endif /* _WINDOWS */
|
|
|
|
#ifndef YIAX_API
|
|
#define YIAX_API
|
|
#endif
|
|
|
|
/**
|
|
* Holds all Telephony Engine related classes.
|
|
*/
|
|
namespace TelEngine {
|
|
|
|
class IAXInfoElement;
|
|
class IAXInfoElementString;
|
|
class IAXInfoElementNumeric;
|
|
class IAXInfoElementBinary;
|
|
class IAXFullFrame;
|
|
class IAXFrameOut;
|
|
class IAXEvent;
|
|
class IAXEngine;
|
|
|
|
#define IAX_PROTOCOL_VERSION 0x0002 // Protocol version
|
|
#define IAX2_MAX_CALLNO 32767 // Max call number value
|
|
#define IAX2_MAX_TRANSINFRAMELIST 127 // Max transaction incoming frame list
|
|
|
|
/**
|
|
* This class holds a single Information Element with no data
|
|
* @short A single IAX2 Information Element
|
|
*/
|
|
class YIAX_API IAXInfoElement : public RefObject
|
|
{
|
|
public:
|
|
/**
|
|
* Information Element enumeration types
|
|
*/
|
|
enum Type {
|
|
textframe = 0x00, // Text Used internally only to generate an event of type Text
|
|
CALLED_NUMBER = 0x01, // Text
|
|
CALLING_NUMBER = 0x02, // Text
|
|
CALLING_ANI = 0x03, // Text
|
|
CALLING_NAME = 0x04, // Text
|
|
CALLED_CONTEXT = 0x05, // Text
|
|
USERNAME = 0x06, // Text
|
|
PASSWORD = 0x07, // Text
|
|
CAPABILITY = 0x08, // DW
|
|
FORMAT = 0x09, // DW
|
|
LANGUAGE = 0x0a, // Text
|
|
VERSION = 0x0b, // W Value: IAX_PROTOCOL_VERSION
|
|
ADSICPE = 0x0c, // W
|
|
DNID = 0x0d, // Text
|
|
AUTHMETHODS = 0x0e, // W
|
|
CHALLENGE = 0x0f, // Text
|
|
MD5_RESULT = 0x10, // Text
|
|
RSA_RESULT = 0x11, // Text
|
|
APPARENT_ADDR = 0x12, // BIN
|
|
REFRESH = 0x13, // W
|
|
DPSTATUS = 0x14, // W
|
|
CALLNO = 0x15, // W Max value: IAX2_MAX_CALLNO
|
|
CAUSE = 0x16, // Text
|
|
IAX_UNKNOWN = 0x17, // B
|
|
MSGCOUNT = 0x18, // W
|
|
AUTOANSWER = 0x19, // Null
|
|
MUSICONHOLD = 0x1a, // Text
|
|
TRANSFERID = 0x1b, // DW
|
|
RDNIS = 0x1c, // Text
|
|
PROVISIONING = 0x1d, // BIN
|
|
AESPROVISIONING = 0x1e, // BIN
|
|
DATETIME = 0x1f, // DW
|
|
DEVICETYPE = 0x20, // Text
|
|
SERVICEIDENT = 0x21, // BIN
|
|
FIRMWAREVER = 0x22, // W
|
|
FWBLOCKDESC = 0x23, // DW
|
|
FWBLOCKDATA = 0x24, // BIN
|
|
PROVVER = 0x25, // DW
|
|
CALLINGPRES = 0x26, // B
|
|
CALLINGTON = 0x27, // B
|
|
CALLINGTNS = 0x28, // W
|
|
SAMPLINGRATE = 0x29, // DW
|
|
CAUSECODE = 0x2a, // B
|
|
ENCRYPTION = 0x2b, // B
|
|
ENKEY = 0x2c, // BIN
|
|
CODEC_PREFS = 0x2d, // Text
|
|
RR_JITTER = 0x2e, // DW
|
|
RR_LOSS = 0x2f, // DW
|
|
RR_PKTS = 0x30, // DW
|
|
RR_DELAY = 0x31, // W
|
|
RR_DROPPED = 0x32, // DW
|
|
RR_OOO = 0x33, // DW
|
|
};
|
|
|
|
/**
|
|
* Constructor
|
|
* @param type Type of this IE
|
|
*/
|
|
inline IAXInfoElement(Type type) : m_type(type) {}
|
|
|
|
/**
|
|
* Destructor
|
|
*/
|
|
virtual ~IAXInfoElement() {}
|
|
|
|
/**
|
|
* Get the type of this IE
|
|
* @return Type of this IE
|
|
*/
|
|
inline Type type() const
|
|
{ return m_type; }
|
|
|
|
/**
|
|
* Constructs a buffer containing this Information Element
|
|
* @param buf Destination buffer
|
|
*/
|
|
virtual void toBuffer(DataBlock& buf);
|
|
|
|
/**
|
|
* Add this element to a string
|
|
* @param buf Destination string
|
|
*/
|
|
virtual void toString(String& buf);
|
|
|
|
/**
|
|
* Get the text associated with an IE type value
|
|
* @param ieCode Numeric code of the IE
|
|
* @return Pointer to the IE text or 0 if it doesn't exist
|
|
*/
|
|
static inline const char* ieText(u_int8_t ieCode)
|
|
{ return lookup(ieCode,s_ieData); }
|
|
|
|
|
|
private:
|
|
static TokenDict s_ieData[];// Association between IE type and text
|
|
Type m_type; // Type of this IE
|
|
};
|
|
|
|
/**
|
|
* This class holds a single Information Element with text data
|
|
* @short A single IAX2 text Information Element
|
|
*/
|
|
class YIAX_API IAXInfoElementString : public IAXInfoElement
|
|
{
|
|
public:
|
|
/**
|
|
* Constructor
|
|
* @param type Type of this IE
|
|
* @param buf Source buffer to construct this IE
|
|
* @param len Buffer length
|
|
*/
|
|
inline IAXInfoElementString(Type type, const char* buf, unsigned len) : IAXInfoElement(type), m_strData(buf,(int)len)
|
|
{}
|
|
|
|
/**
|
|
* Destructor
|
|
*/
|
|
virtual ~IAXInfoElementString() {}
|
|
|
|
/**
|
|
* Get the data length
|
|
* @return The data length
|
|
*/
|
|
inline int length() const
|
|
{ return m_strData.length(); }
|
|
|
|
/**
|
|
* Get the data
|
|
* @return The data
|
|
*/
|
|
inline String& data()
|
|
{ return m_strData; }
|
|
|
|
/**
|
|
* Constructs a buffer containing this Information Element
|
|
* @param buf Destination buffer
|
|
*/
|
|
virtual void toBuffer(DataBlock& buf);
|
|
|
|
/**
|
|
* Add this element to a string
|
|
* @param buf Destination string
|
|
*/
|
|
virtual void toString(String& buf)
|
|
{ buf << m_strData; }
|
|
|
|
private:
|
|
String m_strData; // IE text data
|
|
};
|
|
|
|
/**
|
|
* This class holds a single Information Element with 1, 2 or 4 byte(s) length data
|
|
* @short A single IAX2 numeric Information Element
|
|
*/
|
|
class IAXInfoElementNumeric : public IAXInfoElement
|
|
{
|
|
public:
|
|
/**
|
|
* Constructor
|
|
* @param type Type of this IE
|
|
* @param val Source value to construct this IE
|
|
* @param len Value length
|
|
*/
|
|
IAXInfoElementNumeric(Type type, u_int32_t val, u_int8_t len);
|
|
|
|
/**
|
|
* Destructor
|
|
*/
|
|
virtual ~IAXInfoElementNumeric() {}
|
|
|
|
/**
|
|
* Get the data length
|
|
* @return The data length
|
|
*/
|
|
inline int length() const
|
|
{ return m_length; }
|
|
|
|
/**
|
|
* Get the data
|
|
* @return The data
|
|
*/
|
|
inline u_int32_t data() const
|
|
{ return m_numericData; }
|
|
|
|
/**
|
|
* Constructs a buffer containing this Information Element
|
|
* @param buf Destination buffer
|
|
*/
|
|
virtual void toBuffer(DataBlock& buf);
|
|
|
|
/**
|
|
* Add this element to a string
|
|
* @param buf Destination string
|
|
*/
|
|
virtual void toString(String& buf);
|
|
|
|
private:
|
|
u_int8_t m_length; // IE data length
|
|
u_int32_t m_numericData; // IE numeric data
|
|
};
|
|
|
|
/**
|
|
* This class holds a single Information Element with binary data
|
|
* @short A single IAX2 numeric Information Element
|
|
*/
|
|
class YIAX_API IAXInfoElementBinary : public IAXInfoElement
|
|
{
|
|
public:
|
|
/**
|
|
* Constructor
|
|
* @param type Type of this IE
|
|
* @param buf Source buffer to construct this IE
|
|
* @param len Buffer length
|
|
*/
|
|
IAXInfoElementBinary(Type type, unsigned char* buf, unsigned len) : IAXInfoElement(type), m_data(buf,len)
|
|
{}
|
|
|
|
/**
|
|
* Destructor
|
|
*/
|
|
virtual ~IAXInfoElementBinary() {}
|
|
|
|
/**
|
|
* Get the data length
|
|
* @return The data length
|
|
*/
|
|
inline int length() const
|
|
{ return m_data.length(); }
|
|
|
|
/**
|
|
* Get the data
|
|
* @return The data
|
|
*/
|
|
inline DataBlock& data()
|
|
{ return m_data; }
|
|
|
|
/**
|
|
* Constructs a buffer containing this Information Element
|
|
* @param buf Destination buffer
|
|
*/
|
|
virtual void toBuffer(DataBlock& buf);
|
|
|
|
/**
|
|
* Constructs an APPARENT_ADDR information element from a SocketAddr object
|
|
* @param addr Source object
|
|
* @return A valid IAXInfoElementBinary pointer
|
|
*/
|
|
static IAXInfoElementBinary* packIP(const SocketAddr& addr);
|
|
|
|
/**
|
|
* Decode an APPARENT_ADDR information element and copy it to a SocketAddr object
|
|
* @param addr Destination object
|
|
* @param ie Source IE
|
|
* @return False if ie is 0
|
|
*/
|
|
static bool unpackIP(SocketAddr& addr, IAXInfoElementBinary* ie);
|
|
|
|
/**
|
|
* Add this element to a string
|
|
* @param buf Destination string
|
|
*/
|
|
virtual void toString(String& buf);
|
|
|
|
private:
|
|
DataBlock m_data; // IE binary data
|
|
};
|
|
|
|
/**
|
|
* Management class for a list of Information Elements
|
|
* @short Information Element container
|
|
*/
|
|
class YIAX_API IAXIEList
|
|
{
|
|
public:
|
|
/**
|
|
* Constructor
|
|
*/
|
|
inline IAXIEList() : m_invalidIEList(false)
|
|
{}
|
|
|
|
/**
|
|
* Constructor. Construct the list from an IAXFullFrame object
|
|
* @param frame Source object
|
|
* @param incoming True if it is an incoming frame
|
|
*/
|
|
inline IAXIEList(const IAXFullFrame* frame, bool incoming = true) : m_invalidIEList(false)
|
|
{ createFromFrame(frame,incoming); }
|
|
|
|
/**
|
|
* Destructor
|
|
*/
|
|
inline ~IAXIEList()
|
|
{}
|
|
|
|
/**
|
|
* Get the invalid IE list flag
|
|
* @return False if the last frame parse was unsuccessful
|
|
*/
|
|
inline bool invalidIEList() const
|
|
{ return m_invalidIEList; }
|
|
|
|
/**
|
|
* Clear the list
|
|
*/
|
|
inline void clear()
|
|
{ m_list.clear(); }
|
|
|
|
/**
|
|
* Insert a VERSION Information Element in the list if not already done
|
|
*/
|
|
void insertVersion();
|
|
|
|
/**
|
|
* Get the validity of the VERSION Information Element of the list if any
|
|
* @return False if version is not IAX_PROTOCOL_VERSION or the list doesn't contain a VERSION Information Element
|
|
*/
|
|
inline bool validVersion() {
|
|
u_int32_t ver = 0xFFFF;
|
|
getNumeric(IAXInfoElement::VERSION,ver);
|
|
return ver == IAX_PROTOCOL_VERSION;
|
|
}
|
|
|
|
/**
|
|
* Append an Information Element to the list
|
|
* @param ie IAXInfoElement pointer to append
|
|
*/
|
|
inline void appendIE(IAXInfoElement* ie)
|
|
{ m_list.append(ie); }
|
|
|
|
/**
|
|
* Append an Information Element to the list
|
|
* @param type The type of the IAXInfoElement to append
|
|
*/
|
|
inline void appendNull(IAXInfoElement::Type type)
|
|
{ m_list.append(new IAXInfoElement(type)); }
|
|
|
|
/**
|
|
* Append a text Information Element to the list from a String
|
|
* @param type The type of the IAXInfoElementString to append
|
|
* @param src The source
|
|
*/
|
|
inline void appendString(IAXInfoElement::Type type, const String& src)
|
|
{ m_list.append(new IAXInfoElementString(type,src.c_str(),src.length())); }
|
|
|
|
/**
|
|
* Append a text Information Element to the list from a buffer
|
|
* @param type The type of the IAXInfoElementString to append
|
|
* @param src The source
|
|
* @param len Source length
|
|
*/
|
|
inline void appendString(IAXInfoElement::Type type, unsigned char* src, unsigned len)
|
|
{ m_list.append(new IAXInfoElementString(type,(char*)src,len)); }
|
|
|
|
/**
|
|
* Append a numeric Information Element to the list
|
|
* @param type The type of the IAXInfoElementNumeric to append
|
|
* @param value The source
|
|
* @param len Source length
|
|
*/
|
|
inline void appendNumeric(IAXInfoElement::Type type, u_int32_t value, u_int8_t len)
|
|
{ m_list.append(new IAXInfoElementNumeric(type,value,len)); }
|
|
|
|
/**
|
|
* Append a binary Information Element to the list
|
|
* @param type The type of the IAXInfoElementBinary to append
|
|
* @param data The source data to append
|
|
* @param len Source length
|
|
*/
|
|
inline void appendBinary(IAXInfoElement::Type type, unsigned char* data, unsigned len)
|
|
{ m_list.append(new IAXInfoElementBinary(type,data,len)); }
|
|
|
|
/**
|
|
* Construct the list from an IAXFullFrame object.
|
|
* On exit m_invalidIEList will contain the opposite of the returned value
|
|
* @param frame Source object
|
|
* @param incoming True if it is an incoming frame
|
|
* @return False if the frame contains invalid IEs
|
|
*/
|
|
bool createFromFrame(const IAXFullFrame* frame, bool incoming = true);
|
|
|
|
/**
|
|
* Construct a buffer from this list
|
|
* @param buf Destination buffer
|
|
*/
|
|
void toBuffer(DataBlock& buf);
|
|
|
|
/**
|
|
* Add this list to a string
|
|
* @param dest Destination string
|
|
* @param indent Optional indent for each element
|
|
*/
|
|
void toString(String& dest, const char* indent = 0);
|
|
|
|
/**
|
|
* Get an IAXInfoElement from the list
|
|
* @param type The desired type
|
|
* @return An IAXInfoElement pointer or 0 if the list doesn't contain an IE of this type
|
|
*/
|
|
IAXInfoElement* getIE(IAXInfoElement::Type type);
|
|
|
|
/**
|
|
* Get the data of a list item into a String. Before any operation dest is cleared
|
|
* @param type The desired type
|
|
* @param dest The destination String
|
|
* @return False if the list doesn't contain an IE of this type
|
|
*/
|
|
bool getString(IAXInfoElement::Type type, String& dest);
|
|
|
|
/**
|
|
* Get the data of a list item into a numeric destination
|
|
* @param type The desired type
|
|
* @param dest The destination
|
|
* @return False if the list doesn't contain an IE of this type
|
|
*/
|
|
bool getNumeric(IAXInfoElement::Type type, u_int32_t& dest);
|
|
|
|
/**
|
|
* Get the data of a list item into a DataBlock. Before any operation dest is cleared
|
|
* @param type The desired type
|
|
* @param dest The destination buffer
|
|
* @return False if the list doesn't contain an IE of this type
|
|
*/
|
|
bool getBinary(IAXInfoElement::Type type, DataBlock& dest);
|
|
|
|
private:
|
|
bool m_invalidIEList; // Invalid IE flag
|
|
ObjList m_list; // The IE list
|
|
};
|
|
|
|
/**
|
|
* This class holds the enumeration values for authentication methods
|
|
* @short Wrapper class for authentication methods values
|
|
*/
|
|
class YIAX_API IAXAuthMethod
|
|
{
|
|
public:
|
|
/**
|
|
* Authentication method enumeration types
|
|
*/
|
|
enum Type {
|
|
Text = 1,
|
|
MD5 = 2,
|
|
RSA = 4,
|
|
};
|
|
|
|
/**
|
|
* Create a string list from authentication methods
|
|
* @param dest The destination
|
|
* @param auth The authentication methods as ORed bits
|
|
* @param sep The separator to use
|
|
*/
|
|
static void authList(String& dest, u_int16_t auth, char sep);
|
|
|
|
static TokenDict s_texts[];
|
|
};
|
|
|
|
/**
|
|
* This class holds the enumeration values for audio and video formats
|
|
* @short Wrapper class for audio and video formats
|
|
*/
|
|
class YIAX_API IAXFormat
|
|
{
|
|
public:
|
|
/**
|
|
* Audio format enumeration types
|
|
*/
|
|
enum Audio {
|
|
G723_1 = (1 << 0),
|
|
GSM = (1 << 1),
|
|
ULAW = (1 << 2),
|
|
ALAW = (1 << 3),
|
|
MP3 = (1 << 4),
|
|
ADPCM = (1 << 5),
|
|
SLIN = (1 << 6),
|
|
LPC10 = (1 << 7),
|
|
G729A = (1 << 8),
|
|
SPEEX = (1 << 9),
|
|
ILBC = (1 << 10),
|
|
};
|
|
|
|
/**
|
|
* Video format enumeration types
|
|
*/
|
|
enum Video {
|
|
JPEG = (1 << 16),
|
|
PNG = (1 << 17),
|
|
H261 = (1 << 18),
|
|
H263 = (1 << 19),
|
|
};
|
|
|
|
/**
|
|
* Create a string list from formats
|
|
* @param dest The destination
|
|
* @param formats The formats
|
|
* @param sep The separator to use
|
|
*/
|
|
static void formatList(String& dest, u_int32_t formats, char sep = ',');
|
|
|
|
/**
|
|
* Get the text associated with an audio format
|
|
* @param audio The desired format
|
|
* @return A pointer to the text associated with the format or 0 if the format doesn't exist
|
|
*/
|
|
static inline const char* audioText(u_int32_t audio)
|
|
{ return lookup(audio,audioData); }
|
|
|
|
/**
|
|
* Get the text associated with a video format
|
|
* @param video The desired format
|
|
* @return A pointer to the text associated with the format or 0 if the format doesn't exist
|
|
*/
|
|
static inline const char* videoText(u_int32_t video)
|
|
{ return lookup(video,videoData); }
|
|
|
|
/**
|
|
* Keep the texts associated with the audio formats
|
|
*/
|
|
static TokenDict audioData[];
|
|
|
|
/**
|
|
* Keep the texts associated with the video formats
|
|
*/
|
|
static TokenDict videoData[];
|
|
};
|
|
|
|
/**
|
|
* This class holds the enumeration values for IAX control (subclass)
|
|
* @short Wrapper class for subclasses of frames of type IAX
|
|
*/
|
|
class YIAX_API IAXControl
|
|
{
|
|
public:
|
|
/**
|
|
* IAX control (subclass) enumeration types
|
|
*/
|
|
enum Type {
|
|
New = 0x01,
|
|
Ping = 0x02,
|
|
Pong = 0x03,
|
|
Ack = 0x04,
|
|
Hangup = 0x05,
|
|
Reject = 0x06,
|
|
Accept = 0x07,
|
|
AuthReq = 0x08,
|
|
AuthRep = 0x09,
|
|
Inval = 0x0a,
|
|
LagRq = 0x0b,
|
|
LagRp = 0x0c,
|
|
RegReq = 0x0d,
|
|
RegAuth = 0x0e,
|
|
RegAck = 0x0f,
|
|
RegRej = 0x10,
|
|
RegRel = 0x11,
|
|
VNAK = 0x12,
|
|
DpReq = 0x13,
|
|
DpRep = 0x14,
|
|
Dial = 0x15,
|
|
TxReq = 0x16,
|
|
TxCnt = 0x17,
|
|
TxAcc = 0x18,
|
|
TxReady = 0x19,
|
|
TxRel = 0x1a,
|
|
TxRej = 0x1b,
|
|
Quelch = 0x1c,
|
|
Unquelch = 0x1d,
|
|
Poke = 0x1e,
|
|
//Reserved = 0x1f,
|
|
MWI = 0x20,
|
|
Unsupport = 0x21,
|
|
Transfer = 0x22,
|
|
Provision = 0x23,
|
|
FwDownl = 0x24,
|
|
FwData = 0x25,
|
|
};
|
|
|
|
/**
|
|
* Get the string associated with the given IAX control type
|
|
* @param type The requested type
|
|
* @return The text if type is valid or 0
|
|
*/
|
|
static inline const char* typeText(int type)
|
|
{ return lookup(type,s_types,0); }
|
|
|
|
private:
|
|
static TokenDict s_types[]; // Keep the association between IAX control codes and their name
|
|
};
|
|
|
|
/**
|
|
* This class holds all data needded to manage an IAX frame
|
|
* @short This class holds an IAX frame
|
|
*/
|
|
class YIAX_API IAXFrame : public RefObject
|
|
{
|
|
public:
|
|
/**
|
|
* IAX frame type enumeration
|
|
*/
|
|
enum Type {
|
|
DTMF = 0x01,
|
|
Voice = 0x02,
|
|
Video = 0x03,
|
|
Control = 0x04,
|
|
Null = 0x05,
|
|
IAX = 0x06,
|
|
Text = 0x07,
|
|
Image = 0x08,
|
|
HTML = 0x09,
|
|
Noise = 0x0a,
|
|
};
|
|
|
|
/**
|
|
* Constructor. Constructs an incoming frame
|
|
* @param type Frame type
|
|
* @param sCallNo Source call number
|
|
* @param tStamp Frame timestamp
|
|
* @param retrans Retransmission flag
|
|
* @param buf IE buffer
|
|
* @param len IE buffer length
|
|
*/
|
|
IAXFrame(Type type, u_int16_t sCallNo, u_int32_t tStamp, bool retrans,
|
|
const unsigned char* buf, unsigned int len);
|
|
|
|
/**
|
|
* Destructor
|
|
*/
|
|
virtual ~IAXFrame();
|
|
|
|
/**
|
|
* Get the type of this frame as enumeration
|
|
* @return The type of this frame as enumeration
|
|
*/
|
|
inline Type type() const
|
|
{ return m_type; }
|
|
|
|
/**
|
|
* Get the data buffer of the frame
|
|
* @return The data buffer of the frame
|
|
*/
|
|
inline DataBlock& data()
|
|
{ return m_data; }
|
|
|
|
/**
|
|
* Get the retransmission flag of this frame
|
|
* @return The retransmission flag of this frame
|
|
*/
|
|
inline bool retrans() const
|
|
{ return m_retrans; }
|
|
|
|
/**
|
|
* Get the source call number of this frame
|
|
* @return The source call number of this frame
|
|
*/
|
|
inline u_int16_t sourceCallNo() const
|
|
{ return m_sCallNo; }
|
|
|
|
/**
|
|
* Get the timestamp of this frame
|
|
* @return The timestamp of this frame
|
|
*/
|
|
inline u_int32_t timeStamp() const
|
|
{ return m_tStamp; }
|
|
|
|
/**
|
|
* Get a pointer to this frame if it is a full frame
|
|
* @return A pointer to this frame if it is a full frame or 0
|
|
*/
|
|
virtual const IAXFullFrame* fullFrame() const;
|
|
|
|
/**
|
|
* Parse a received buffer and returns a IAXFrame pointer if valid
|
|
* @param buf Received buffer
|
|
* @param len Buffer length
|
|
* @param engine The IAXEngine who requested the operation
|
|
* @param addr The source address
|
|
* @return A frame pointer on success or 0
|
|
*/
|
|
static IAXFrame* parse(const unsigned char* buf, unsigned int len, IAXEngine* engine = 0, const SocketAddr* addr = 0);
|
|
|
|
/**
|
|
* Pack a subclass value according to IAX protocol
|
|
* @param value Value to pack
|
|
* @return The packed subclass value or 0 if invalid (>255 and not a power of 2)
|
|
*/
|
|
static u_int8_t packSubclass(u_int32_t value);
|
|
|
|
/**
|
|
* Unpack a subclass value according to IAX protocol
|
|
* @param value Value to unpack
|
|
* @return The unpacked subclass value
|
|
*/
|
|
static u_int32_t unpackSubclass(u_int8_t value);
|
|
|
|
/**
|
|
* Get the string associated with the given IAX frame type
|
|
* @param type The requested type
|
|
* @return The text if type is valid or 0
|
|
*/
|
|
static inline const char* typeText(int type)
|
|
{ return lookup(type,s_types,0); }
|
|
|
|
protected:
|
|
/**
|
|
* Contains the frame's IE list for an incoming frame or the whole frame for an outgoing one
|
|
*/
|
|
DataBlock m_data;
|
|
|
|
/**
|
|
* Retransmission flag
|
|
*/
|
|
bool m_retrans;
|
|
|
|
private:
|
|
static TokenDict s_types[]; // Keep the association between IAX frame types and their names
|
|
Type m_type; // Frame type
|
|
u_int16_t m_sCallNo; // Source call number
|
|
u_int32_t m_tStamp; // Frame timestamp
|
|
};
|
|
|
|
/**
|
|
* This class holds all data needded to manage an IAX full frame
|
|
* @short This class holds an IAX full frame
|
|
*/
|
|
class YIAX_API IAXFullFrame : public IAXFrame
|
|
{
|
|
public:
|
|
/**
|
|
* IAX frame subclass enumeration types for frames of type Control
|
|
*/
|
|
enum ControlType {
|
|
Hangup = 0x01,
|
|
//Ring = 0x02,
|
|
Ringing = 0x03,
|
|
Answer = 0x04,
|
|
Busy = 0x05,
|
|
Congestion = 0x08,
|
|
FlashHook = 0x09,
|
|
Option = 0x0b,
|
|
KeyRadio = 0x0c,
|
|
UnkeyRadio = 0x0d,
|
|
Progressing = 0x0e,
|
|
Proceeding = 0x0f,
|
|
Hold = 0x10,
|
|
Unhold = 0x11,
|
|
VidUpdate = 0x12,
|
|
};
|
|
|
|
/**
|
|
* Constructor. Constructs an incoming full frame
|
|
* @param type Frame type
|
|
* @param subclass Frame subclass
|
|
* @param sCallNo Source (remote) call number
|
|
* @param dCallNo Destination (local) call number
|
|
* @param oSeqNo Outgoing sequence number
|
|
* @param iSeqNo Incoming (expected) sequence number
|
|
* @param tStamp Frame timestamp
|
|
* @param retrans Retransmission flag
|
|
* @param buf IE buffer
|
|
* @param len IE buffer length
|
|
*/
|
|
IAXFullFrame(Type type, u_int32_t subclass, u_int16_t sCallNo, u_int16_t dCallNo,
|
|
unsigned char oSeqNo, unsigned char iSeqNo,
|
|
u_int32_t tStamp, bool retrans,
|
|
const unsigned char* buf, unsigned int len);
|
|
|
|
/**
|
|
* Constructor. Constructs an outgoing full frame
|
|
* @param type Frame type
|
|
* @param subclass Frame subclass
|
|
* @param sCallNo Source (remote) call number
|
|
* @param dCallNo Destination (local) call number
|
|
* @param oSeqNo Outgoing sequence number
|
|
* @param iSeqNo Incoming (expected) sequence number
|
|
* @param tStamp Frame timestamp
|
|
* @param buf IE buffer
|
|
* @param len IE buffer length
|
|
*/
|
|
IAXFullFrame(Type type, u_int32_t subclass, u_int16_t sCallNo, u_int16_t dCallNo,
|
|
unsigned char oSeqNo, unsigned char iSeqNo,
|
|
u_int32_t tStamp,
|
|
const unsigned char* buf = 0, unsigned int len = 0);
|
|
|
|
/**
|
|
* Destructor
|
|
*/
|
|
virtual ~IAXFullFrame();
|
|
|
|
/**
|
|
* Get the destination call number
|
|
* @return The destination call number
|
|
*/
|
|
inline u_int16_t destCallNo() const
|
|
{ return m_dCallNo; }
|
|
|
|
/**
|
|
* Get the outgoing sequence number
|
|
* @return The outgoing sequence number
|
|
*/
|
|
inline unsigned char oSeqNo() const
|
|
{ return m_oSeqNo; }
|
|
|
|
/**
|
|
* Get the incoming sequence number
|
|
* @return The incoming sequence number
|
|
*/
|
|
inline unsigned char iSeqNo() const
|
|
{ return m_iSeqNo; }
|
|
|
|
/**
|
|
* Get the subclass of this frame
|
|
* @return The subclass of this frame
|
|
*/
|
|
inline u_int32_t subclass() const
|
|
{ return m_subclass; }
|
|
|
|
/**
|
|
* Get a pointer to this frame if it is a full frame
|
|
* @return A pointer to this frame
|
|
*/
|
|
virtual const IAXFullFrame* fullFrame() const;
|
|
|
|
/**
|
|
* Fill a string with this frame
|
|
* @param dest The string to fill
|
|
* @param local The local address
|
|
* @param remote The remote address
|
|
* @param incoming True if it is an incoming frame
|
|
*/
|
|
void toString(String& dest, const SocketAddr& local, const SocketAddr& remote,
|
|
bool incoming) const;
|
|
|
|
/**
|
|
* Get the string associated with the given IAX control type
|
|
* @param type The requested control type
|
|
* @return The text if type is valid or 0
|
|
*/
|
|
static inline const char* controlTypeText(int type)
|
|
{ return lookup(type,s_controlTypes,0); }
|
|
|
|
private:
|
|
static TokenDict s_controlTypes[]; // Keep the association between control types and their names
|
|
u_int16_t m_dCallNo; // Destination call number
|
|
unsigned char m_oSeqNo; // Out sequence number
|
|
unsigned char m_iSeqNo; // In sequence number
|
|
u_int32_t m_subclass; // Subclass
|
|
};
|
|
|
|
/**
|
|
* This class holds all data needded to manage an outgoing IAX full frame
|
|
* @short This class holds an outgoing IAX full frame
|
|
*/
|
|
class YIAX_API IAXFrameOut : public IAXFullFrame
|
|
{
|
|
public:
|
|
/**
|
|
* Constructor. Constructs an outgoing full frame
|
|
* @param type Frame type
|
|
* @param subclass Frame subclass
|
|
* @param sCallNo Source (remote) call number
|
|
* @param dCallNo Destination (local) call number
|
|
* @param oSeqNo Outgoing sequence number
|
|
* @param iSeqNo Incoming (expected) sequence number
|
|
* @param tStamp Frame timestamp
|
|
* @param buf IE buffer
|
|
* @param len IE buffer length
|
|
* @param retransCount Retransmission counter
|
|
* @param retransInterval Time interval to the next retransmission
|
|
* @param ackOnly Acknoledge only flag. If true, the frame only expects an ACK
|
|
*/
|
|
inline IAXFrameOut(Type type, u_int32_t subclass, u_int16_t sCallNo, u_int16_t dCallNo,
|
|
unsigned char oSeqNo, unsigned char iSeqNo, u_int32_t tStamp, const unsigned char* buf, unsigned int len,
|
|
u_int16_t retransCount, u_int32_t retransInterval, bool ackOnly)
|
|
: IAXFullFrame(type,subclass,sCallNo,dCallNo,oSeqNo,iSeqNo,tStamp,buf,len),
|
|
m_ack(false), m_ackOnly(ackOnly), m_retransCount(retransCount), m_retransTimeInterval(retransInterval),
|
|
m_nextTransTime(Time::msecNow() + m_retransTimeInterval)
|
|
{}
|
|
|
|
/**
|
|
* Destructor
|
|
*/
|
|
virtual ~IAXFrameOut()
|
|
{}
|
|
|
|
/**
|
|
* Get the timeout (retransmission counter) of this frame
|
|
* @return True if the retransmission counter is 0
|
|
*/
|
|
inline bool timeout() const
|
|
{ return m_retransCount == 0; }
|
|
|
|
/**
|
|
* Ask the frame if it's time for retransmit
|
|
* @param time Current time
|
|
* @return True if it's time to retransmit
|
|
*/
|
|
inline bool timeForRetrans(u_int64_t time) const
|
|
{ return time > m_nextTransTime; }
|
|
|
|
/**
|
|
* Set the retransmission flag of this frame
|
|
*/
|
|
void setRetrans();
|
|
|
|
/**
|
|
* Update the retransmission counter and the time to next retransmission
|
|
*/
|
|
void transmitted();
|
|
|
|
/**
|
|
* Get the acknoledged flag of this frame
|
|
* @return The acknoledged flag of this frame
|
|
*/
|
|
inline bool ack() const
|
|
{ return m_ack; }
|
|
|
|
/**
|
|
* Set the acknoledged flag of this frame
|
|
*/
|
|
inline void setAck()
|
|
{ m_ack = true; }
|
|
|
|
/**
|
|
* Get the acknoledge only flag of this frame
|
|
* @return The acknoledge only flag of this frame
|
|
*/
|
|
inline bool ackOnly() const
|
|
{ return m_ackOnly; }
|
|
|
|
/**
|
|
* Increase the timeout for acknoledged authentication frames sent and set the counter to 1
|
|
* @param nextTransTime Next transmission time
|
|
*/
|
|
void adjustAuthTimeout(u_int64_t nextTransTime);
|
|
|
|
private:
|
|
bool m_ack; // Acknoledge flag
|
|
bool m_ackOnly; // Frame need only ACK as a response
|
|
u_int16_t m_retransCount; // Retransmission counter
|
|
u_int32_t m_retransTimeInterval; // Retransmission interval
|
|
u_int64_t m_nextTransTime; // Next transmission time
|
|
};
|
|
|
|
/**
|
|
* Handle meta trunk frame with timestamps
|
|
* @short Meta trunk frame
|
|
*/
|
|
class YIAX_API IAXMetaTrunkFrame : public RefObject, public Mutex
|
|
{
|
|
public:
|
|
/**
|
|
* Constructor. Constructs an outgoing meta trunk frame
|
|
* @param engine The engine that owns this frame
|
|
* @param addr Remote peer address
|
|
*/
|
|
IAXMetaTrunkFrame(IAXEngine* engine, const SocketAddr& addr);
|
|
|
|
/**
|
|
* Destructor
|
|
*/
|
|
virtual ~IAXMetaTrunkFrame();
|
|
|
|
/**
|
|
* Get the remote peer address
|
|
* @return The remote peer address
|
|
*/
|
|
inline const SocketAddr& addr() const
|
|
{ return m_addr; }
|
|
|
|
/**
|
|
* Get the timestamp of this frame
|
|
* @return The timestamp of this frame
|
|
*/
|
|
inline u_int32_t timestamp()
|
|
{ return m_timestamp; }
|
|
|
|
/**
|
|
* Set the timestamp of this frame
|
|
* @param tStamp Timestamp value to set
|
|
*/
|
|
void setTimestamp(u_int32_t tStamp);
|
|
|
|
/**
|
|
* Add a mini frame. If no room, send before adding
|
|
* @param sCallNo Sorce call number
|
|
* @param data Mini frame data
|
|
* @param tStamp Mini frame timestamp
|
|
* @return False if the frame was sent and the write operation failed
|
|
*/
|
|
bool add(u_int16_t sCallNo, const DataBlock& data, u_int32_t tStamp);
|
|
|
|
/**
|
|
* Send this frame to remote peer
|
|
* @param tStamp Frame timestamp
|
|
* @return The result of the write operation
|
|
*/
|
|
bool send(u_int32_t tStamp);
|
|
|
|
private:
|
|
u_int8_t* m_data; // Data buffer
|
|
u_int16_t m_dataAddIdx; // Current add index
|
|
u_int32_t m_timestamp; // Frame timestamp
|
|
IAXEngine* m_engine; // The engine that owns this frame
|
|
SocketAddr m_addr; // Remote peer address
|
|
};
|
|
|
|
/**
|
|
* This class holds all the data needded for the management of an IAX2 transaction
|
|
* which might be a call leg, a register/unregister or a poke one
|
|
* @short An IAX2 transaction
|
|
*/
|
|
class YIAX_API IAXTransaction : public RefObject, public Mutex
|
|
{
|
|
friend class IAXEvent;
|
|
friend class IAXEngine;
|
|
public:
|
|
/**
|
|
* The transaction type as enumeration
|
|
*/
|
|
enum Type {
|
|
Incorrect, // Unsupported/unknown type
|
|
New, // Media exchange call
|
|
RegReq, // Registration
|
|
RegRel, // Registration release
|
|
Poke, // Ping
|
|
//FwDownl,
|
|
};
|
|
|
|
/**
|
|
* The transaction state as enumeration
|
|
*/
|
|
enum State {
|
|
Connected, // Call leg established (Accepted) for transactions of type New
|
|
NewLocalInvite, // New outgoing transaction: Poke/New/RegReq/RegRel
|
|
NewLocalInvite_AuthRecv, // Auth request received for an outgoing transaction
|
|
NewLocalInvite_RepSent, // Auth reply sent for an outgoing transaction
|
|
NewRemoteInvite, // New incoming transaction: Poke/New/RegReq/RegRel
|
|
NewRemoteInvite_AuthSent, // Auth sent for an incoming transaction
|
|
NewRemoteInvite_RepRecv, // Auth reply received for an incoming transaction
|
|
Unknown, // Initial state
|
|
Terminated, // Terminated. No more frames accepted
|
|
Terminating, // Terminating. Wait for ACK or timeout to terminate
|
|
};
|
|
|
|
/**
|
|
* Constructs an incoming transaction from a received full frame with an IAX
|
|
* control message that needs a new transaction
|
|
* @param engine The engine that owns this transaction
|
|
* @param frame A valid full frame
|
|
* @param lcallno Local call number
|
|
* @param addr Address from where the frame was received
|
|
* @param data Pointer to arbitrary user data
|
|
*/
|
|
static IAXTransaction* factoryIn(IAXEngine* engine, IAXFullFrame* frame, u_int16_t lcallno, const SocketAddr& addr,
|
|
void* data = 0);
|
|
|
|
/**
|
|
* Constructs an outgoing transaction with an IAX control message that needs a new transaction
|
|
* @param engine The engine that owns this transaction
|
|
* @param type Transaction type
|
|
* @param lcallno Local call number
|
|
* @param addr Address to use
|
|
* @param ieList Starting IE list
|
|
* @param data Pointer to arbitrary user data
|
|
*/
|
|
static IAXTransaction* factoryOut(IAXEngine* engine, Type type, u_int16_t lcallno, const SocketAddr& addr,
|
|
IAXIEList& ieList, void* data = 0);
|
|
|
|
/**
|
|
* Destructor
|
|
*/
|
|
virtual ~IAXTransaction();
|
|
|
|
/**
|
|
* The IAX engine this transaction belongs to
|
|
* @return Pointer to the IAXEngine of this transaction
|
|
*/
|
|
inline IAXEngine* getEngine() const
|
|
{ return m_engine; }
|
|
|
|
/**
|
|
* Get the type of this transaction
|
|
* @return The type of the transaction as enumeration
|
|
*/
|
|
inline Type type() const
|
|
{ return m_type; }
|
|
|
|
/**
|
|
* Get the state of this transaction
|
|
* @return The state of the transaction as enumeration
|
|
*/
|
|
inline State state() const
|
|
{ return m_state; }
|
|
|
|
/**
|
|
* Get the timestamp of this transaction
|
|
* @return The timestamp of this transaction
|
|
*/
|
|
inline u_int64_t timeStamp() const
|
|
{ return Time::msecNow() - m_timeStamp; }
|
|
|
|
/**
|
|
* Get the direction of this transaction
|
|
* @return True if it is an outgoing transaction
|
|
*/
|
|
inline bool outgoing() const
|
|
{ return m_localInitTrans; }
|
|
|
|
/**
|
|
* Store a pointer to arbitrary user data
|
|
* @param data User provided pointer
|
|
*/
|
|
inline void setUserData(void* data)
|
|
{ m_userdata = data; }
|
|
|
|
/**
|
|
* Return the opaque user data stored in the transaction
|
|
* @return Pointer set by user
|
|
*/
|
|
inline void* getUserData() const
|
|
{ return m_userdata; }
|
|
|
|
/**
|
|
* Retrive the local call number
|
|
* @return 15-bit local call number
|
|
*/
|
|
inline u_int16_t localCallNo() const
|
|
{ return m_lCallNo; }
|
|
|
|
/**
|
|
* Retrive the remote call number
|
|
* @return 15-bit remote call number
|
|
*/
|
|
inline u_int16_t remoteCallNo() const
|
|
{ return m_rCallNo; }
|
|
|
|
/**
|
|
* Retrive the remote host+port address
|
|
* @return A reference to the remote address
|
|
*/
|
|
inline const SocketAddr& remoteAddr() const
|
|
{ return m_addr; }
|
|
|
|
/**
|
|
* Retrive the username
|
|
* @return A reference to the username
|
|
*/
|
|
inline const String& username()
|
|
{ return m_username; }
|
|
|
|
/**
|
|
* Retrive the calling number
|
|
* @return A reference to the calling number
|
|
*/
|
|
inline const String& callingNo()
|
|
{ return m_callingNo; }
|
|
|
|
/**
|
|
* Retrive the calling name
|
|
* @return A reference to the calling name
|
|
*/
|
|
inline const String& callingName()
|
|
{ return m_callingName; }
|
|
|
|
/**
|
|
* Retrive the called number
|
|
* @return A reference to the called number
|
|
*/
|
|
inline const String& calledNo()
|
|
{ return m_calledNo; }
|
|
|
|
/**
|
|
* Retrive the called context
|
|
* @return A reference to the called context
|
|
*/
|
|
inline const String& calledContext()
|
|
{ return m_calledContext; }
|
|
|
|
/**
|
|
* Retrive the challenge sent/received during authentication
|
|
* @return A reference to the challenge
|
|
*/
|
|
inline const String& challenge()
|
|
{ return m_challenge; }
|
|
|
|
/**
|
|
* Retrive the media format used during initialization
|
|
* @return The initial media format
|
|
*/
|
|
inline u_int32_t format()
|
|
{ return m_format; }
|
|
|
|
/**
|
|
* Retrive the incoming media format
|
|
* @return The incoming media format
|
|
*/
|
|
inline u_int32_t formatIn()
|
|
{ return m_formatIn; }
|
|
|
|
/**
|
|
* Retrive the outgoing media format
|
|
* @return The outgoing media format
|
|
*/
|
|
inline u_int32_t formatOut() const
|
|
{ return m_formatOut; }
|
|
|
|
/**
|
|
* Retrive the media capability of this transaction
|
|
* @return The media capability of this transaction
|
|
*/
|
|
inline u_int32_t capability() const
|
|
{ return m_capability; }
|
|
|
|
/**
|
|
* Retrive the expiring time for a register/unregister transaction
|
|
* @return The expiring time for a register/unregister transaction
|
|
*/
|
|
inline u_int32_t expire() const
|
|
{ return m_expire; }
|
|
|
|
/**
|
|
* Retrive the authentication data sent/received during authentication
|
|
* @return A reference to the authentication data
|
|
*/
|
|
inline const String& authdata()
|
|
{ return m_authdata; }
|
|
|
|
/**
|
|
* Process a frame from remote peer
|
|
* This method is thread safe.
|
|
* @param frame IAX frame belonging to this transaction to process
|
|
* @return 'this' if successful or NULL if the frame is invalid
|
|
*/
|
|
IAXTransaction* processFrame(IAXFrame* frame);
|
|
|
|
/**
|
|
* Process received mini frame data
|
|
* @param data Received data
|
|
* @param tStamp Mini frame timestamp
|
|
* @param voice True if received mini frame inside a Voice full frame
|
|
* @return 0
|
|
*/
|
|
IAXTransaction* processMedia(DataBlock& data, u_int32_t tStamp, bool voice = false);
|
|
|
|
/**
|
|
* Send media data to remote peer. Update the outgoing media format if changed
|
|
* @param data Data to send
|
|
* @param format Data format
|
|
* @return 'this' if successful or 0
|
|
*/
|
|
IAXTransaction* sendMedia(const DataBlock& data, u_int32_t format);
|
|
|
|
/**
|
|
* Get an IAX event from the queue
|
|
* This method is thread safe.
|
|
* @param time The time this method was called
|
|
* @return Pointer to an IAXEvent or 0 if none available
|
|
*/
|
|
IAXEvent* getEvent(u_int64_t time);
|
|
|
|
/**
|
|
* Get the maximum allowed number of full frames in the incoming frame list
|
|
* @return The maximum allowed number of full frames in the incoming frame list
|
|
*/
|
|
static unsigned char getMaxFrameList();
|
|
|
|
/**
|
|
* Set the maximum allowed number of full frames in the incoming frame list
|
|
* @param value The new value of m_maxInFrames
|
|
* @return False if value is greater then IAX2_MAX_TRANSINFRAMELIST
|
|
*/
|
|
static bool setMaxFrameList(unsigned char value);
|
|
|
|
/**
|
|
* Send an ANSWER frame to remote peer
|
|
* This method is thread safe
|
|
* @return False if the current transaction state is not Connected
|
|
*/
|
|
inline bool sendAnswer()
|
|
{ return sendConnected(IAXFullFrame::Answer); }
|
|
|
|
/**
|
|
* Send a RINGING frame to remote peer
|
|
* This method is thread safe
|
|
* @return False if the current transaction state is not Connected
|
|
*/
|
|
inline bool sendRinging()
|
|
{ return sendConnected(IAXFullFrame::Ringing); }
|
|
|
|
/**
|
|
* Send a PROCEEDING frame to remote peer
|
|
* This method is thread safe
|
|
* @return False if the current transaction state is not Connected
|
|
*/
|
|
inline bool sendProgress()
|
|
{ return sendConnected(IAXFullFrame::Proceeding); }
|
|
|
|
/**
|
|
* Send an ACCEPT/REGACK frame to remote peer
|
|
* This method is thread safe
|
|
* @return False if the transaction type is not New and state is NewRemoteInvite or NewRemoteInvite_AuthRep or
|
|
* if the transaction type is not RegReq and state is NewRemoteInvite or
|
|
* type is not RegReq/RegRel and state is NewRemoteInvite_AuthRep
|
|
*/
|
|
bool sendAccept();
|
|
|
|
/**
|
|
* Send a HANGUP frame to remote peer
|
|
* This method is thread safe
|
|
* @param cause Optional reason for hangup
|
|
* @param code Optional code of reason
|
|
* @return False if the transaction type is not New or state is Terminated/Terminating
|
|
*/
|
|
bool sendHangup(const char* cause = 0, u_int8_t code = 0);
|
|
|
|
/**
|
|
* Send a REJECT/REGREJ frame to remote peer
|
|
* This method is thread safe
|
|
* @param cause Optional reason for reject
|
|
* @param code Optional code of reason
|
|
* @return False if the transaction type is not New/RegReq/RegRel or state is Terminated/Terminating
|
|
*/
|
|
bool sendReject(const char* cause = 0, u_int8_t code = 0);
|
|
|
|
/**
|
|
* Send an AUTHREQ/REGAUTH frame to remote peer
|
|
* This method is thread safe
|
|
* @return False if the current transaction state is not NewRemoteInvite
|
|
*/
|
|
bool sendAuth();
|
|
|
|
/**
|
|
* Send an AUTHREP/REGREQ/REGREL frame to remote peer as a response to AUTHREQ/REGREQ/REGREL
|
|
* This method is thread safe
|
|
* @param response Response to send
|
|
* @return False if the current transaction state is not NewLocalInvite_AuthRecv
|
|
*/
|
|
bool sendAuthReply(const String& response);
|
|
|
|
/**
|
|
* Send a DTMF frame to remote peer
|
|
* This method is thread safe
|
|
* @param dtmf DTMF char to send
|
|
* @return False if the current transaction state is not Connected or dtmf is grater then 127
|
|
*/
|
|
inline bool sendDtmf(u_int8_t dtmf)
|
|
{ return dtmf <= 127 ? sendConnected((IAXFullFrame::ControlType)dtmf,IAXFrame::DTMF) : false; }
|
|
|
|
/**
|
|
* Send a TEXT frame to remote peer
|
|
* This method is thread safe
|
|
* @param text Text to send
|
|
* @return False if the current transaction state is not Connected
|
|
*/
|
|
bool sendText(const char* text);
|
|
|
|
/**
|
|
* Send a NOISE frame to remote peer
|
|
* This method is thread safe
|
|
* @param noise Noise value to send
|
|
* @return False if the current transaction state is not Connected or noise is grater then 127
|
|
*/
|
|
inline bool sendNoise(u_int8_t noise)
|
|
{ return noise <= 127 ? sendConnected((IAXFullFrame::ControlType)noise,IAXFrame::Noise) : false; }
|
|
|
|
/**
|
|
* Abort a registration transaction
|
|
* This method is thread safe
|
|
* @return False transaction is not a registration one or is already terminating
|
|
*/
|
|
bool abortReg();
|
|
|
|
/**
|
|
* Enable trunking for this transaction
|
|
* @param trunkFrame Pointer to IAXMetaTrunkFrame used to send trunked media
|
|
* @return False trunking is already enabled for this transactio or trunkFrame is 0
|
|
*/
|
|
bool enableTrunking(IAXMetaTrunkFrame* trunkFrame);
|
|
|
|
/**
|
|
* Print transaction data on stdin
|
|
*/
|
|
void print();
|
|
|
|
/**
|
|
* Standard message sent if unsupported/unknown/none authentication methosd was received
|
|
*/
|
|
static String s_iax_modNoAuthMethod;
|
|
|
|
/**
|
|
* Standard message sent if unsupported/unknown/none media format was received
|
|
*/
|
|
static String s_iax_modNoMediaFormat;
|
|
|
|
/**
|
|
* Standard message sent if the received authentication data is incorrect
|
|
*/
|
|
static String s_iax_modInvalidAuth;
|
|
|
|
/**
|
|
* Standard message sent if a received frame doesn't have an username information element
|
|
*/
|
|
static String s_iax_modNoUsername;
|
|
|
|
protected:
|
|
/**
|
|
* Constructor: constructs an incoming transaction from a received full frame with an IAX
|
|
* control message that needs a new transaction
|
|
* @param engine The engine that owns this transaction
|
|
* @param frame A valid full frame
|
|
* @param lcallno Local call number
|
|
* @param addr Address from where the frame was received
|
|
* @param data Pointer to arbitrary user data
|
|
*/
|
|
IAXTransaction(IAXEngine* engine, IAXFullFrame* frame, u_int16_t lcallno, const SocketAddr& addr,
|
|
void* data = 0);
|
|
|
|
/**
|
|
* Constructor: constructs an outgoing transaction with an IAX control message that needs a new transaction
|
|
* @param engine The engine that owns this transaction
|
|
* @param type Transaction type: see Type enumeration
|
|
* @param lcallno Local call number
|
|
* @param addr Address to use
|
|
* @param ieList Starting IE list
|
|
* @param data Pointer to arbitrary user data
|
|
*/
|
|
IAXTransaction(IAXEngine* engine, Type type, u_int16_t lcallno, const SocketAddr& addr, IAXIEList& ieList,
|
|
void* data = 0);
|
|
|
|
/**
|
|
* Init data members from an IE list
|
|
* @param ieList IE list to init from
|
|
*/
|
|
void init(IAXIEList& ieList);
|
|
|
|
/**
|
|
* Increment sequence numbers (inbound or outbound) for the frames that need it
|
|
* @param frame Received frame if inbound is true, otherwise a transmitted one
|
|
* @param inbound True for inbound frames
|
|
* @return True if incremented.
|
|
*/
|
|
bool incrementSeqNo(const IAXFullFrame* frame, bool inbound);
|
|
|
|
/**
|
|
* Test if frame is acceptable (not an out of order or a late one)
|
|
* @param frame Frame to test
|
|
* @return True if frame can be added to incoming frame list
|
|
*/
|
|
bool isFrameAcceptable(const IAXFullFrame* frame);
|
|
|
|
/**
|
|
* Change the transaction state
|
|
* @param newState the new transaction state
|
|
* @return False if trying to change a termination state into a non termination one
|
|
*/
|
|
bool changeState(State newState);
|
|
|
|
/**
|
|
* Terminate the transaction.
|
|
* @param evType IAXEvent type to generate
|
|
* @param local If true it is a locally generated event
|
|
* @param frame Frame to build event from
|
|
* @param createIEList If true create IE list in the generated event
|
|
* @return Pointer to a valid IAXEvent
|
|
*/
|
|
IAXEvent* terminate(u_int8_t evType, bool local, const IAXFullFrame* frame = 0, bool createIEList = true);
|
|
|
|
/**
|
|
* Wait for ACK to terminate the transaction. No more events will be generated
|
|
* @param evType IAXEvent type to generate
|
|
* @param local If true it is a locally generated event
|
|
* @param frame Frame to build event from
|
|
* @return Pointer to a valid IAXEvent
|
|
*/
|
|
IAXEvent* waitForTerminate(u_int8_t evType, bool local, const IAXFullFrame* frame);
|
|
|
|
/**
|
|
* Constructs an IAXFrameOut frame, send it to remote peer and put it in the transmission list
|
|
* This method is thread safe
|
|
* @param type Frame type
|
|
* @param subclass Frame subclass
|
|
* @param data Frame IE list
|
|
* @param len Frame IE list length
|
|
* @param tStamp Frame timestamp. If 0 the transaction timestamp will be used
|
|
* @param ackOnly Frame's acknoledge only flag
|
|
*/
|
|
void postFrame(IAXFrame::Type type, u_int32_t subclass, void* data = 0, u_int16_t len = 0, u_int32_t tStamp = 0,
|
|
bool ackOnly = false);
|
|
|
|
/**
|
|
* Send a full frame to remote peer
|
|
* @param frame Frame to send
|
|
* @param vnak If true the transmission is a response to a VNAK frame
|
|
* @return True on success
|
|
*/
|
|
bool sendFrame(IAXFrameOut* frame, bool vnak = false);
|
|
|
|
/**
|
|
* Create an event
|
|
* @param evType Event type
|
|
* @param local If true it is a locally generated event.
|
|
* @param frame Frame to create from
|
|
* @param newState The transaction new state
|
|
* @return Pointer to an IAXEvent or 0 (invalid IE list)
|
|
*/
|
|
IAXEvent* createEvent(u_int8_t evType, bool local, const IAXFullFrame* frame, State newState);
|
|
|
|
/**
|
|
* Create an event from a received frame that is a response to a sent frame and
|
|
* change the transaction state to newState. Remove the response from incoming list.
|
|
* @param frame Frame to create response for
|
|
* @param findType Frame type to find
|
|
* @param findSubclass Frame subclass to find
|
|
* @param evType Event type to generate
|
|
* @param local Local flag for the generated event.
|
|
* @param newState New transaction state if an event was generated
|
|
* @return Pointer to an IAXEvent or 0 (invalid IE list)
|
|
*/
|
|
IAXEvent* createResponse(IAXFrameOut* frame, u_int8_t findType, u_int8_t findSubclass, u_int8_t evType, bool local, State newState);
|
|
|
|
/**
|
|
* Find a response for a previously sent frame
|
|
* @param frame Frame to find response for
|
|
* @param delFrame Delete frame flag. If true on exit, a response was found
|
|
* @return Pointer to an IAXEvent or 0
|
|
*/
|
|
IAXEvent* getEventResponse(IAXFrameOut* frame, bool& delFrame);
|
|
|
|
/**
|
|
* Find a response for a previously sent frame if the transaction type is New
|
|
* @param frame Frame to find response for
|
|
* @param delFrame Delete frame flag. If true on exit, a response was found
|
|
* @return Pointer to an IAXEvent or 0
|
|
*/
|
|
IAXEvent* getEventResponse_New(IAXFrameOut* frame, bool& delFrame);
|
|
|
|
/**
|
|
* Process an authentication request. If valid, send an authentication reply
|
|
* @param event Already generated event
|
|
* @return Pointer to a valid IAXEvent
|
|
*/
|
|
IAXEvent* processAuthReq(IAXEvent* event);
|
|
|
|
/**
|
|
* Process an accept. If not valid (call m_engine->acceptFormatAndCapability) send a reject.
|
|
* Otherwise return the event
|
|
* @param event Already generated event
|
|
* @return Pointer to a valid IAXEvent
|
|
*/
|
|
IAXEvent* processAccept(IAXEvent* event);
|
|
|
|
/**
|
|
* Process an authentication reply
|
|
* @param event Already generated event
|
|
* @return Pointer to a valid IAXEvent
|
|
*/
|
|
IAXEvent* processAuthRep(IAXEvent* event);
|
|
|
|
/**
|
|
* Find a response for a previously sent frame if the transaction type is RegReq/RegRel
|
|
* @param frame Frame to find response for
|
|
* @param delFrame Delete frame flag. If true on exit, a response was found
|
|
* @return Pointer to an IAXEvent or 0
|
|
*/
|
|
IAXEvent* getEventResponse_Reg(IAXFrameOut* frame, bool& delFrame);
|
|
|
|
/**
|
|
* Update transaction data from the event
|
|
* @param event Already generated event
|
|
* @return The received event
|
|
*/
|
|
IAXEvent* processRegAck(IAXEvent* event);
|
|
|
|
/**
|
|
* Find out if an incoming frame would start a transaction
|
|
* @param frame Frame to process
|
|
* @param delFrame Delete frame flag. If true on exit, frame is valid
|
|
* @return Pointer to an IAXEvent or 0
|
|
*/
|
|
IAXEvent* getEventStartTrans(IAXFullFrame* frame, bool& delFrame);
|
|
|
|
/**
|
|
* Find out if a frame is a remote request
|
|
* @param frame Frame to process
|
|
* @param delFrame Delete rame flag. If true on exit, a request was found
|
|
* @return Pointer to an IAXEvent or 0
|
|
*/
|
|
IAXEvent* getEventRequest(IAXFullFrame* frame, bool& delFrame);
|
|
|
|
/**
|
|
* Find out if a frame is a remote request if transaction type is New
|
|
* @param frame Frame to process
|
|
* @param delFrame Delete rame flag. If true on exit, a request was found
|
|
* @return Pointer to an IAXEvent or 0
|
|
*/
|
|
IAXEvent* getEventRequest_New(IAXFullFrame* frame, bool& delFrame);
|
|
|
|
/**
|
|
* Search for a frame in m_inFrames having the given type and subclass
|
|
* @param type Frame type to find.
|
|
* @param subclass Frame subclass to find.
|
|
* @return Pointer to frame if found or 0.
|
|
*/
|
|
IAXFullFrame* findInFrame(IAXFrame::Type type, u_int32_t subclass);
|
|
|
|
/**
|
|
* Search in m_inFrames for a frame with the same timestamp as frameOut and deletes it.
|
|
* @param frameOut Frame to find response for
|
|
* @param type Frame type to find
|
|
* @param subclass Frame subclass to find
|
|
* @return True if found.
|
|
*/
|
|
bool findInFrameTimestamp(const IAXFullFrame* frameOut, IAXFrame::Type type, u_int32_t subclass);
|
|
|
|
/**
|
|
* Search in m_inFrames for an ACK frame which confirm the received frame and deletes it
|
|
* @param frameOut Frame to find response for
|
|
* @return True if found.
|
|
*/
|
|
bool findInFrameAck(const IAXFullFrame* frameOut);
|
|
|
|
/**
|
|
* Acknoledge the last received full frame
|
|
*/
|
|
void ackInFrames();
|
|
|
|
/**
|
|
* Send a frame to remote peer in state Connected
|
|
* This method is thread safe
|
|
* @param subclass Frame subclass to send
|
|
* @param frametype Frame type to send
|
|
* @return False if the current transaction state is not Connected
|
|
*/
|
|
bool sendConnected(IAXFullFrame::ControlType subclass, IAXFrame::Type frametype = IAXFrame::Control);
|
|
|
|
/**
|
|
* Send an ACK frame
|
|
* @param frame Aknoledged frame
|
|
*/
|
|
void sendAck(const IAXFullFrame* frame);
|
|
|
|
/**
|
|
* Send an INVAL frame
|
|
*/
|
|
void sendInval();
|
|
|
|
/**
|
|
* Send an VNAK frame
|
|
*/
|
|
void sendVNAK();
|
|
|
|
/**
|
|
* Send an Unsupport frame
|
|
* @param subclass Unsupported frame's subclass
|
|
*/
|
|
void sendUnsupport(u_int32_t subclass);
|
|
|
|
/**
|
|
* Internal protocol outgoing frames processing (PING/LAGRQ)
|
|
* @param frame Frame to process
|
|
* @param delFrame Delete frame flag. If true on exit, a response was found
|
|
* @return 0.
|
|
*/
|
|
IAXEvent* processInternalOutgoingRequest(IAXFrameOut* frame, bool& delFrame);
|
|
|
|
/**
|
|
* Internal protocol incoming frames processing (PING/LAGRQ)
|
|
* @param frame Frame to process
|
|
* @param delFrame Delete frame flag. If true on exit, a request was found
|
|
* @return 0.
|
|
*/
|
|
IAXEvent* processInternalIncomingRequest(const IAXFullFrame* frame, bool& delFrame);
|
|
|
|
/**
|
|
* Process mid call control frames
|
|
* @param frame Frame to process
|
|
* @param delFrame Delete frame flag. If true on exit, a request was found
|
|
* @return A valid IAXEvent or 0
|
|
*/
|
|
IAXEvent* processMidCallControl(const IAXFullFrame* frame, bool& delFrame);
|
|
|
|
/**
|
|
* Process mid call IAX control frames
|
|
* @param frame Frame to process
|
|
* @param delFrame Delete frame flag. If true on exit, a request was found
|
|
* @return A valid IAXEvent or 0
|
|
*/
|
|
IAXEvent* processMidCallIAXControl(const IAXFullFrame* frame, bool& delFrame);
|
|
|
|
/**
|
|
* Test if frame is a Reject/RegRej frame
|
|
* @param frame Frame to process.
|
|
* @param delFrame Delete frame flag. If true on exit, a request was found
|
|
* @return A valid IAXEvent or 0.
|
|
*/
|
|
IAXEvent* remoteRejectCall(const IAXFullFrame* frame, bool& delFrame);
|
|
|
|
/**
|
|
* Terminate the transaction if state is Terminating on a remote request
|
|
* @param time Current time
|
|
* @return A valid IAXEvent or 0
|
|
*/
|
|
IAXEvent* getEventTerminating(u_int64_t time);
|
|
|
|
/**
|
|
* Process received Voice frames
|
|
* @param frame Received voice frame
|
|
* @return 0
|
|
*/
|
|
IAXTransaction* processVoiceFrame(const IAXFullFrame* frame);
|
|
|
|
/**
|
|
* Send all frames from outgoing queue with outbound sequence number starting with seqNo.
|
|
* @param seqNo Requested sequence number
|
|
* @return 0
|
|
*/
|
|
IAXTransaction* retransmitOnVNAK(u_int16_t seqNo);
|
|
|
|
/**
|
|
* Generate an Accept event after internally accepting a transaction
|
|
* @return A valid IAXEvent
|
|
*/
|
|
IAXEvent* internalAccept();
|
|
|
|
/**
|
|
* Generate a Reject event after internally rejecting a transaction
|
|
* @param reason The reason of rejecting
|
|
* @return A valid IAXEvent
|
|
*/
|
|
IAXEvent* internalReject(String& reason);
|
|
|
|
/**
|
|
* Event terminated feedback
|
|
* This method is thread safe
|
|
* @param event The event notifying termination
|
|
*/
|
|
void eventTerminated(IAXEvent* event);
|
|
|
|
/**
|
|
* Set the current event
|
|
* @param event The event notifying termination
|
|
* @return event
|
|
*/
|
|
inline IAXEvent* keepEvent(IAXEvent* event) {
|
|
m_currentEvent = event;
|
|
return event;
|
|
}
|
|
|
|
private:
|
|
// Params
|
|
bool m_localInitTrans; // True: local initiated transaction
|
|
bool m_localReqEnd; // Local client requested terminate
|
|
Type m_type; // Transaction type
|
|
State m_state; // Transaction state
|
|
u_int64_t m_timeStamp; // Transaction creation timestamp
|
|
u_int32_t m_timeout; // Transaction timeout (in seconds) on remote termination request
|
|
SocketAddr m_addr; // Socket
|
|
u_int16_t m_lCallNo; // Local peer call id
|
|
u_int16_t m_rCallNo; // Remote peer call id
|
|
unsigned char m_oSeqNo; // Outgoing frame sequence number
|
|
unsigned char m_iSeqNo; // Incoming frame sequence number
|
|
IAXEngine* m_engine; // Engine that owns this transaction
|
|
void* m_userdata; // Arbitrary user data
|
|
u_int32_t m_lastFullFrameOut; // Last transmitted full frame timestamp
|
|
u_int16_t m_lastMiniFrameOut; // Last transmitted mini frame timestamp
|
|
u_int32_t m_lastMiniFrameIn; // Last received mini frame timestamp
|
|
u_int16_t m_lastAck; // Last ack'd received frame's oseqno
|
|
Mutex m_mutexInMedia; // Keep received media thread safe
|
|
IAXEvent* m_pendingEvent; // Pointer to a pending event or 0
|
|
IAXEvent* m_currentEvent; // Pointer to last generated event or 0
|
|
// Outgoing frames management
|
|
ObjList m_outFrames; // Transaction & protocol control outgoing frames
|
|
u_int16_t m_retransCount; // Retransmission counter. 0 --> Timeout
|
|
u_int32_t m_retransInterval; // Frame retransmission interval
|
|
// Incoming frames management
|
|
ObjList m_inFrames; // Transaction & protocol control incoming frames
|
|
static unsigned char m_maxInFrames; // Max frames number allowed in m_inFrames
|
|
// Call leg management
|
|
u_int32_t m_pingInterval; // Ping remote peer interval
|
|
u_int64_t m_timeToNextPing; // Time of the next Ping
|
|
// Statistics
|
|
u_int32_t m_inTotalFramesCount; // Total received frames
|
|
u_int32_t m_inOutOfOrderFrames; // Total out of order frames
|
|
u_int32_t m_inDroppedFrames; // Total dropped frames
|
|
// Data
|
|
IAXAuthMethod::Type m_authmethod; // Authentication method to use
|
|
String m_username; // Username
|
|
String m_callingNo; // Calling number
|
|
String m_callingName; // Calling name
|
|
String m_calledNo; // Called number
|
|
String m_calledContext; // Called context
|
|
String m_challenge; // Challenge
|
|
String m_authdata; // Auth data received with auth reply
|
|
u_int32_t m_expire; // Registration expiring time
|
|
u_int32_t m_format; // Media format used for initial negotiation
|
|
u_int32_t m_formatIn; // Incoming media format
|
|
u_int32_t m_formatOut; // Outgoing media format
|
|
u_int32_t m_capability; // Media capability of this transaction
|
|
// Meta trunking
|
|
IAXMetaTrunkFrame* m_trunkFrame; // Reference to a trunk frame if trunking is enabled for this transaction
|
|
};
|
|
|
|
/**
|
|
* This class holds an event generated by a transaction
|
|
* @short Event class
|
|
*/
|
|
class YIAX_API IAXEvent
|
|
{
|
|
friend class IAXTransaction;
|
|
friend class IAXConnectionlessTransaction;
|
|
public:
|
|
/**
|
|
* Event type as enumeration
|
|
*/
|
|
enum Type {
|
|
Invalid = 0, // Invalid frame received
|
|
Terminated, // Transaction terminated
|
|
Timeout, // Transaction timeout
|
|
NotImplemented, // Feature not implemented
|
|
New, // New remote transaction
|
|
AuthReq, // Auth request
|
|
AuthRep, // Auth reply
|
|
Accept, // Request accepted
|
|
Hangup, // Remote hangup
|
|
Reject, // Remote reject
|
|
Busy, // Call busy
|
|
Text, // Text frame received
|
|
Dtmf, // DTMF frame received
|
|
Noise, // Noise frame received
|
|
Answer, // Call answered
|
|
Quelch, // Quelch the call
|
|
Unquelch, // Unquelch the call
|
|
Progressing, // Call progressing
|
|
Ringing, // Ringing
|
|
};
|
|
|
|
/**
|
|
* Destructor
|
|
* Dereferences the transaction possibly causing its destruction
|
|
*/
|
|
~IAXEvent();
|
|
|
|
/**
|
|
* Get the type of this event
|
|
* @return The type of the event as enumeratio
|
|
*/
|
|
inline Type type() const
|
|
{ return m_type; }
|
|
|
|
/**
|
|
* Check if this is a locally generated event
|
|
* @return True if it is a locally generated event
|
|
*/
|
|
inline bool local() const
|
|
{ return m_local; }
|
|
|
|
/**
|
|
* Check if this is a transaction finalization event
|
|
* @return True if the transaction has finalized and will be destroyed
|
|
*/
|
|
inline bool final() const
|
|
{ return m_final; }
|
|
|
|
/**
|
|
* Set the final flag.
|
|
*/
|
|
inline void setFinal()
|
|
{ m_final = true; }
|
|
|
|
/**
|
|
* Get the type of the frame that generated the event
|
|
* If 0 (internal event), the event consumer must delete the event
|
|
* @return Frame type
|
|
*/
|
|
inline u_int8_t frameType()
|
|
{ return m_frameType; }
|
|
|
|
/**
|
|
* Get the subclass of the frame that generated the event
|
|
* @return Frame subclass
|
|
*/
|
|
inline u_int32_t subclass()
|
|
{ return m_subClass; }
|
|
|
|
/**
|
|
* Get the IAX engine this event belongs to, if any
|
|
* @return The IAX engine this event belongs to, if any
|
|
*/
|
|
inline IAXEngine* getEngine() const
|
|
{ return m_transaction ? m_transaction->getEngine() : 0; }
|
|
|
|
/**
|
|
* Get the IAX transaction that generated the event, if any
|
|
* @return The IAX transaction that generated the event, if any
|
|
*/
|
|
inline IAXTransaction* getTransaction() const
|
|
{ return m_transaction; }
|
|
|
|
/**
|
|
* Get the opaque user data stored in the transaction
|
|
* @return The opaque user data stored in the transaction
|
|
*/
|
|
inline void* getUserData() const
|
|
{ return m_transaction ? m_transaction->getUserData() : 0; }
|
|
|
|
/**
|
|
* Get the IE list
|
|
* @return IE list reference
|
|
*/
|
|
inline IAXIEList& getList()
|
|
{ return m_ieList; }
|
|
|
|
protected:
|
|
/**
|
|
* Constructor
|
|
* @param type Event type
|
|
* @param local Local flag
|
|
* @param final Final flag
|
|
* @param transaction IAX transaction that generated the event
|
|
* @param frameType The type of the frame that generated the event
|
|
* @param subclass The subclass of the frame that generated the event
|
|
*/
|
|
IAXEvent(Type type, bool local, bool final, IAXTransaction* transaction, u_int8_t frameType = 0, u_int32_t subclass = 0);
|
|
|
|
/**
|
|
* Constructor
|
|
* @param type Event type
|
|
* @param local Local flag
|
|
* @param final Final flag
|
|
* @param transaction IAX transaction that generated the event
|
|
* @param frame The frame that generated the event
|
|
*/
|
|
IAXEvent(Type type, bool local, bool final, IAXTransaction* transaction, const IAXFullFrame* frame = 0);
|
|
|
|
private:
|
|
inline IAXEvent() {} // Default constructor
|
|
|
|
Type m_type; // Event type
|
|
u_int8_t m_frameType; // Frame type
|
|
u_int32_t m_subClass; // Frame subclass
|
|
bool m_local; // If true the event is generated locally, the receiver MUST not respond
|
|
bool m_final; // Final event flag
|
|
IAXTransaction* m_transaction; // Transaction that generated this event
|
|
IAXIEList m_ieList; // IAXInfoElement list
|
|
};
|
|
|
|
/**
|
|
* This class holds all information needded to manipulate all IAX transactions and events
|
|
* @short IAX engine class
|
|
*/
|
|
class YIAX_API IAXEngine : public DebugEnabler, public Mutex
|
|
{
|
|
public:
|
|
/**
|
|
* Constructor
|
|
* @param iface Address of the interface to use, default all (0.0.0.0)
|
|
* @param port UDP port to run the protocol on
|
|
* @param transListCount Number of entries in the transaction hash table
|
|
* @param retransCount Retransmission counter for each transaction belonging to this engine
|
|
* @param retransInterval Retransmission interval default value in miliseconds
|
|
* @param authTimeout Timeout (in seconds) of acknoledged auth frames sent
|
|
* @param transTimeout Timeout (in seconds) on remote request of transactions belonging to this engine
|
|
* @param maxFullFrameDataLen Max full frame IE list (buffer) length
|
|
* @param format Default media format
|
|
* @param capab Media capabilities of this engine
|
|
* @param trunkSendInterval Send trunk meta frame interval
|
|
* @param authRequired Automatically challenge all clients for authentication
|
|
*/
|
|
IAXEngine(const char* iface, int port, u_int16_t transListCount, u_int16_t retransCount, u_int16_t retransInterval,
|
|
u_int16_t authTimeout, u_int16_t transTimeout, u_int16_t maxFullFrameDataLen,
|
|
u_int32_t format, u_int32_t capab, u_int32_t trunkSendInterval, bool authRequired);
|
|
|
|
/**
|
|
* Destructor
|
|
* Closes all transactions belonging to this engine and flush all queues
|
|
*/
|
|
virtual ~IAXEngine();
|
|
|
|
/**
|
|
* Add a parsed frame to the transaction list
|
|
* @param addr Address from which the frame was received
|
|
* @param frame A parsed IAX frame
|
|
* @return Pointer to the transaction or 0 to deref the frame
|
|
*/
|
|
IAXTransaction* addFrame(const SocketAddr& addr, IAXFrame* frame);
|
|
|
|
/**
|
|
* Add a raw frame to the transaction list
|
|
* @param addr Address from which the message was received
|
|
* @param buf Pointer to the start of the buffer holding the IAX frame
|
|
* @param len Length of the message buffer
|
|
* @return Pointer to the transaction or 0
|
|
*/
|
|
IAXTransaction* addFrame(const SocketAddr& addr, const unsigned char* buf, unsigned int len);
|
|
|
|
/**
|
|
* Process media from remote peer. Descendents must override this method
|
|
* @param transaction IAXTransaction that owns the call leg
|
|
* @param data Media data
|
|
* @param tStamp Media timestamp
|
|
*/
|
|
virtual void processMedia(IAXTransaction* transaction, DataBlock& data, u_int32_t tStamp)
|
|
{}
|
|
|
|
/**
|
|
* Event processor method. Keeps calling getEvent() and passing
|
|
* any events to processEvent() until there are no more events
|
|
* @return True if at least one event was processed
|
|
*/
|
|
bool process();
|
|
|
|
/**
|
|
* Get default frame retransmission counter
|
|
* @return Frame retransmission counter
|
|
*/
|
|
inline u_int16_t retransCount() const
|
|
{ return m_retransCount; }
|
|
|
|
/**
|
|
* Get default frame retransmission starting interval
|
|
* @return Frame retransmission starting interval
|
|
*/
|
|
inline u_int16_t retransInterval() const
|
|
{ return m_retransInterval; }
|
|
|
|
/**
|
|
* Check if a transaction should automatically request authentication
|
|
* @return True to automatically request authentication
|
|
*/
|
|
inline bool authRequired() const
|
|
{ return m_authRequired; }
|
|
|
|
/**
|
|
* Get the timeout (in seconds) of acknoledged auth frames sent
|
|
* @return Auth timeout in seconds
|
|
*/
|
|
inline u_int16_t authTimeout() const
|
|
{ return m_authTimeout; }
|
|
|
|
/**
|
|
* Get the timeout (in seconds) of transactions belonging to this engine
|
|
* @return Timeout (in seconds) of transactions belonging to this engine
|
|
*/
|
|
inline u_int32_t transactionTimeout() const
|
|
{ return m_transTimeout; }
|
|
|
|
/**
|
|
* Get the maximum allowed frame length
|
|
* @return The maximum allowed frame length
|
|
*/
|
|
inline u_int16_t maxFullFrameDataLen() const
|
|
{ return m_maxFullFrameDataLen; }
|
|
|
|
/**
|
|
* Get the default media format
|
|
* @return The default media format
|
|
*/
|
|
inline u_int32_t format() const
|
|
{ return m_format; }
|
|
|
|
/**
|
|
* Get the media capability of this engine
|
|
* @return The media capability of this engine
|
|
*/
|
|
inline u_int32_t capability() const
|
|
{ return m_capability; }
|
|
|
|
/**
|
|
* Read data from socket
|
|
* @param addr Socket to read from
|
|
*/
|
|
void readSocket(SocketAddr& addr);
|
|
|
|
/**
|
|
* Write data to socket.
|
|
* @param buf Data to write
|
|
* @param len Data length
|
|
* @param addr Socket to write to
|
|
* @param frame Optional frame to be printed if debug is DebugAll
|
|
* @return True on success
|
|
*/
|
|
bool writeSocket(const void* buf, int len, const SocketAddr& addr, IAXFullFrame* frame = 0);
|
|
|
|
/**
|
|
* Read events
|
|
*/
|
|
void runGetEvents();
|
|
|
|
/**
|
|
* Removes a transaction from queue. Free the allocated local call number
|
|
* Does not delete it
|
|
* @param transaction Transaction to remove
|
|
*/
|
|
void removeTransaction(IAXTransaction* transaction);
|
|
|
|
/**
|
|
* Return the transactions count
|
|
* This method is thread safe
|
|
* @return Transactions count
|
|
*/
|
|
u_int32_t transactionCount();
|
|
|
|
/**
|
|
* Send an INVAL with call numbers set to 0 to a remote peer to keep it alive
|
|
* @param addr Address to send to
|
|
*/
|
|
void keepAlive(SocketAddr& addr);
|
|
|
|
/**
|
|
* Process a new format received with a Voice frame
|
|
* @param trans Transaction that received the new format
|
|
* @param format The received format
|
|
* @return True if accepted
|
|
*/
|
|
virtual bool voiceFormatChanged(IAXTransaction* trans, u_int32_t format)
|
|
{ return false; }
|
|
|
|
/**
|
|
* Process the initial received format and capability. If accepted on exit will set the transaction format and capability
|
|
* @param trans Transaction that received the new format
|
|
* @return True if accepted
|
|
*/
|
|
bool acceptFormatAndCapability(IAXTransaction* trans);
|
|
|
|
/**
|
|
* Default event handler. event MUST NOT be deleted
|
|
* @param event The event to handle
|
|
*/
|
|
virtual void defaultEventHandler(IAXEvent* event);
|
|
|
|
/**
|
|
* Enable trunking for the given transaction. Allocate a trunk meta frame if needded
|
|
* @param trans Transaction to enable trunking for
|
|
*/
|
|
void enableTrunking(IAXTransaction* trans);
|
|
|
|
/**
|
|
* Remove a trunk meta frame from the queue and deref it
|
|
* @param metaFrame The trunk meta frame to remove
|
|
*/
|
|
void removeTrunkFrame(IAXMetaTrunkFrame* metaFrame);
|
|
|
|
/**
|
|
* Keep calling processTrunkFrames to send trunked media data
|
|
*/
|
|
void runProcessTrunkFrames();
|
|
|
|
/**
|
|
* Get the socket used for engine operation
|
|
* @return Reference to the UDP socket
|
|
*/
|
|
inline Socket& socket()
|
|
{ return m_socket; }
|
|
|
|
/**
|
|
* Get the MD5 data from a challenge and a password
|
|
* @param md5data Destination String
|
|
* @param challenge Challenge source
|
|
* @param password Password source
|
|
*/
|
|
static void getMD5FromChallenge(String& md5data, const String& challenge, const String& password);
|
|
|
|
/**
|
|
* Test if a received response to an authentication request is correct
|
|
* @param md5data Data to compare with
|
|
* @param challenge Received challenge
|
|
* @param password Password source
|
|
*/
|
|
static bool isMD5ChallengeCorrect(const String& md5data, const String& challenge, const String& password);
|
|
|
|
protected:
|
|
/**
|
|
* Process all trunk meta frames in the queue
|
|
* @param time Time of the call
|
|
* @return True if at least one frame was sent
|
|
*/
|
|
bool processTrunkFrames(u_int32_t time = Time::msecNow());
|
|
|
|
/**
|
|
* Default event for connection transactions handler. This method may be overriden to perform custom
|
|
* processing
|
|
* This method is thread safe
|
|
* @param event Event to process
|
|
*/
|
|
virtual void processEvent(IAXEvent* event);
|
|
|
|
/**
|
|
* Get an IAX event from the queue.
|
|
* This method is thread safe.
|
|
* @param time Time of the call
|
|
* @return Pointer to an IAXEvent or 0 if none is available
|
|
*/
|
|
IAXEvent* getEvent(u_int64_t time);
|
|
|
|
/**
|
|
* Generate call number. Update used call numbers list
|
|
* @return Call number or 0 if none available
|
|
*/
|
|
u_int16_t generateCallNo();
|
|
|
|
/**
|
|
* Release a call number
|
|
* @param lcallno Call number to release
|
|
*/
|
|
void releaseCallNo(u_int16_t lcallno);
|
|
|
|
/**
|
|
* Start a transaction based on a local request
|
|
* @param type Transaction type
|
|
* @param addr Remote address to send the request
|
|
* @param ieList First frame IE list
|
|
* @param trunking Enable/disable trunking for this transaction
|
|
* @return IAXTransaction pointer on success.
|
|
*/
|
|
IAXTransaction* startLocalTransaction(IAXTransaction::Type type, const SocketAddr& addr, IAXIEList& ieList, bool trunking = false);
|
|
|
|
private:
|
|
Socket m_socket; // Socket
|
|
ObjList** m_transList; // Full transactions
|
|
ObjList m_incompleteTransList; // Incomplete transactions (no remote call number)
|
|
bool m_lUsedCallNo[IAX2_MAX_CALLNO + 1]; // Used local call numnmbers flags
|
|
int m_lastGetEvIndex; // getEvent: keep last array entry
|
|
// Parameters
|
|
bool m_authRequired; // Automatically request authentication
|
|
int m_maxFullFrameDataLen; // Max full frame data (IE list) length
|
|
u_int16_t m_startLocalCallNo; // Start index of local call number allocation
|
|
u_int16_t m_transListCount; // m_transList count
|
|
u_int16_t m_retransCount; // Retransmission counter for each transaction belonging to this engine
|
|
u_int16_t m_retransInterval; // Retransmission interval default value in miliseconds
|
|
u_int16_t m_authTimeout; // Timeout (in seconds) of acknoledged auth frames sent
|
|
u_int32_t m_transTimeout; // Timeout (in seconds) on remote request of transactions
|
|
// belonging to this engine
|
|
// Media
|
|
u_int32_t m_format; // The default media format
|
|
u_int32_t m_capability; // The media capability
|
|
// Trunking
|
|
Mutex m_mutexTrunk; // Mutex for trunk operations
|
|
ObjList m_trunkList; // Trunk frames list
|
|
u_int32_t m_trunkSendInterval; // Trunk frame send interval
|
|
};
|
|
|
|
}
|
|
|
|
#endif /* __YATEIAX_H */
|
|
|
|
/* vi: set ts=8 sw=4 sts=4 noet: */
|