2c3d47c29c
git-svn-id: http://yate.null.ro/svn/yate/trunk@2612 acf43c95-373e-0410-b603-e72c3f656dc1
1100 lines
36 KiB
C++
1100 lines
36 KiB
C++
/**
|
|
* yatemgcp.h
|
|
* Yet Another MGCP 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 __YATEMGCP_H
|
|
#define __YATEMGCP_H
|
|
|
|
#include <yateclass.h>
|
|
#include <yatemime.h>
|
|
|
|
#ifdef _WINDOWS
|
|
|
|
#ifdef LIBYMGCP_EXPORTS
|
|
#define YMGCP_API __declspec(dllexport)
|
|
#else
|
|
#ifndef LIBYMGCP_STATIC
|
|
#define YMGCP_API __declspec(dllimport)
|
|
#endif
|
|
#endif
|
|
|
|
#endif /* _WINDOWS */
|
|
|
|
#ifndef YMGCP_API
|
|
#define YMGCP_API
|
|
#endif
|
|
|
|
/**
|
|
* Holds all Telephony Engine related classes.
|
|
*/
|
|
namespace TelEngine {
|
|
|
|
class MGCPMessage;
|
|
class MGCPTransaction;
|
|
class MGCPEpInfo;
|
|
class MGCPEndpoint;
|
|
class MGCPEvent;
|
|
class MGCPEngine;
|
|
|
|
/**
|
|
* This class holds an MGCP message, either command or response, along with
|
|
* its parameters. The
|
|
* @short An MGCP command or response
|
|
*/
|
|
class YMGCP_API MGCPMessage : public RefObject
|
|
{
|
|
friend class MGCPTransaction;
|
|
public:
|
|
/**
|
|
* Constructor. Construct an outgoing command message.
|
|
* A transaction id will be requested from the endpoint's engine.
|
|
* The message will be invalidated if failed to get a transaction id or the
|
|
* command name is unknown
|
|
* @param engine The engine sending this message
|
|
* @param name Command name
|
|
* @param ep The id of the endpoint issuing this command
|
|
* @param ver The protocol version to use
|
|
*/
|
|
MGCPMessage(MGCPEngine* engine, const char* name, const char* ep, const char* ver = "MGCP 1.0");
|
|
|
|
/**
|
|
* Constructor. Construct an outgoing response message
|
|
* The message will be invalidated if failed to get a transaction id or the
|
|
* code is greater then 999
|
|
* @param trans The transaction to respond
|
|
* @param code The response code ranging from 0 to 999
|
|
* @param comment Optional response comment
|
|
*/
|
|
MGCPMessage(MGCPTransaction* trans, unsigned int code, const char* comment = 0);
|
|
|
|
/**
|
|
* Destructor
|
|
*/
|
|
virtual ~MGCPMessage();
|
|
|
|
/**
|
|
* Check if this is a valid message
|
|
* @return True if this is a valid message
|
|
*/
|
|
inline bool valid() const
|
|
{ return m_valid; }
|
|
|
|
/**
|
|
* Get the command name or response code text representation of this message
|
|
* @return The command name or response text representation of this message
|
|
*/
|
|
inline const String& name() const
|
|
{ return m_name; }
|
|
|
|
/**
|
|
* Get the response code if this is a response message
|
|
* @return The response code contained in this message
|
|
*/
|
|
inline int code() const
|
|
{ return m_code; }
|
|
|
|
/**
|
|
* Get the protocol version of a command message
|
|
* @return The protocol version of this message
|
|
*/
|
|
inline const String& version() const
|
|
{ return m_version; }
|
|
|
|
/**
|
|
* Get the comment from a response message
|
|
* @return The comment of this message
|
|
*/
|
|
inline const String& comment() const
|
|
{ return m_comment; }
|
|
|
|
/**
|
|
* Check if this is a command (code is a negative value)
|
|
* @return True if this message is a command
|
|
*/
|
|
inline bool isCommand() const
|
|
{ return code() < 0; }
|
|
|
|
/**
|
|
* Check if this is a response message (code is greater then or equal to 100)
|
|
* @return True if this message is a response
|
|
*/
|
|
inline bool isResponse() const
|
|
{ return 100 <= code(); }
|
|
|
|
/**
|
|
* Check if this message is a response ACK (code is between 0 and 99, including the margins)
|
|
* @return True if this message is a response ACK
|
|
*/
|
|
inline bool isAck() const
|
|
{ return 0 <= code() && code() <= 99; }
|
|
|
|
/**
|
|
* Get the message's transaction id
|
|
* @return The message's transaction id
|
|
*/
|
|
inline unsigned int transactionId() const
|
|
{ return m_transaction; }
|
|
|
|
/**
|
|
* Get the message's endpoint id if this is a command
|
|
* @return The message's endpoint id if this is a command
|
|
*/
|
|
inline const String& endpointId() const
|
|
{ return m_endpoint; }
|
|
|
|
/**
|
|
* Convert this message to a string representation to be sent to the remote
|
|
* endpoint or printed to output
|
|
* @param dest Destination string
|
|
*/
|
|
void toString(String& dest) const;
|
|
|
|
/**
|
|
* Parse a received buffer according to RFC 3435. Command and protocol names are converted to upper case.
|
|
* The enpoint id is converted to lower case. Message parameter names are converted to lower case if
|
|
* the engine's flag is set. Message parameter values and SDP(s) are stored unchanged
|
|
* @param engine The receiving engine
|
|
* @param dest The list of received messages
|
|
* @param buffer The buffer to parse
|
|
* @param len The buffer length
|
|
* @param sdpType The MIME SDP content type if the message contains any SDP body
|
|
* @return False on failure, true on success. If failed, the destination
|
|
* list may contain a response message to be sent
|
|
*/
|
|
static bool parse(MGCPEngine* engine, ObjList& dest,
|
|
const unsigned char* buffer, unsigned int len,
|
|
const char* sdpType = "application/sdp");
|
|
|
|
/**
|
|
* Keep the message parameters
|
|
*/
|
|
NamedList params;
|
|
|
|
/**
|
|
* Keep the SDP(s) carried by this message as MimeSdpBody object(s)
|
|
*/
|
|
ObjList sdp;
|
|
|
|
protected:
|
|
/**
|
|
* Constructor. Used by the parser to construct an incoming message
|
|
* @param engine The engine receiving this message
|
|
* @param name Command name or response comment
|
|
* @param code The response code in the range 0 to 999 or -1 if the received
|
|
* message is a command
|
|
* @param transId The id of the transaction owning this message
|
|
* @param epId The id of the endpoint issuing this command
|
|
* @param ver The protocol version
|
|
*/
|
|
MGCPMessage(MGCPEngine* engine, const char* name, int code,
|
|
unsigned int transId, const char* epId, const char* ver);
|
|
|
|
private:
|
|
MGCPMessage() : params("") {} // Avoid using default constructor
|
|
// Decode the message line
|
|
static MGCPMessage* decodeMessage(const char* line, unsigned int len, unsigned int& trans,
|
|
String& error, MGCPEngine* engine);
|
|
// Decode message parameters. Return true if found a line containing a dot
|
|
static bool decodeParams(const unsigned char* buffer, unsigned int len,
|
|
unsigned int& crt, MGCPMessage* msg, String& error, MGCPEngine* engine);
|
|
|
|
String m_name; // Command or string representation of response code
|
|
bool m_valid; // False if this message is invalid
|
|
int m_code; // Response code or -1 if this is a command
|
|
unsigned int m_transaction; // The id of the transaction this message belongs to
|
|
String m_endpoint; // The id of the endpoint issuing this message
|
|
String m_version; // The protocol version
|
|
String m_comment; // The comment attached to a response message
|
|
};
|
|
|
|
/**
|
|
* This class implements an MGCP transaction
|
|
* @short An MGCP transaction
|
|
*/
|
|
class YMGCP_API MGCPTransaction : public RefObject, public Mutex
|
|
{
|
|
friend class MGCPEngine; // Process a received message
|
|
friend class MGCPEvent; // Access to event termination notification
|
|
public:
|
|
/**
|
|
* Transaction state enumeration
|
|
*/
|
|
enum State {
|
|
Invalid = 0, // This is an invalid transaction (constructor failed)
|
|
Initiated = 1, // An initial command message was sent/received
|
|
Trying = 2, // Sent or received a provisional response to the initial message
|
|
Responded = 3, // Sent or received a final response to the initial message
|
|
Ack = 4, // Response was ack'd
|
|
Destroying = 5, // Waiting to be removed from the engine
|
|
};
|
|
|
|
/**
|
|
* Constructor. Construct a transaction from its first message
|
|
* @param engine The engine owning this transaction
|
|
* @param msg The command creating this transaction
|
|
* @param outgoing The direction of this transaction
|
|
* @param address Remote enpoint's address
|
|
*/
|
|
MGCPTransaction(MGCPEngine* engine, MGCPMessage* msg, bool outgoing,
|
|
const SocketAddr& address);
|
|
|
|
/**
|
|
* Destructor
|
|
*/
|
|
virtual ~MGCPTransaction();
|
|
|
|
/**
|
|
* Get the current transaction's state
|
|
* @return The transaction state as enumeration
|
|
*/
|
|
inline State state() const
|
|
{ return m_state; }
|
|
|
|
/**
|
|
* Get the id of this transaction
|
|
* @return The id of this transaction
|
|
*/
|
|
inline unsigned int id() const
|
|
{ return m_id; }
|
|
|
|
/**
|
|
* Get the direction of this transaction
|
|
* @return True if this is an outgoing transaction
|
|
*/
|
|
inline bool outgoing() const
|
|
{ return m_outgoing; }
|
|
|
|
/**
|
|
* Get the id of the endpoint owning this transaction
|
|
* @return The id of the endpoint owning this transaction
|
|
*/
|
|
inline const String& ep() const
|
|
{ return m_endpoint; }
|
|
|
|
/**
|
|
* Get the remote endpoint's IP address
|
|
* @return The remote endpoint's IP address
|
|
*/
|
|
const SocketAddr& addr() const
|
|
{ return m_address; }
|
|
|
|
/**
|
|
* Get the engine owning this transaction
|
|
* @return The engine owning this transaction
|
|
*/
|
|
inline MGCPEngine* engine()
|
|
{ return m_engine; }
|
|
|
|
/**
|
|
* Get the initial command message sent or received by this transaction
|
|
* @return The transaction's initial message
|
|
*/
|
|
inline const MGCPMessage* initial() const
|
|
{ return m_cmd; }
|
|
|
|
/**
|
|
* Get the provisional response message sent or received by this transaction
|
|
* @return The transaction's provisional response message
|
|
*/
|
|
inline const MGCPMessage* msgProvisional() const
|
|
{ return m_provisional; }
|
|
|
|
/**
|
|
* Get the final response message sent or received by this transaction
|
|
* @return The transaction's final response message
|
|
*/
|
|
inline const MGCPMessage* msgResponse() const
|
|
{ return m_response; }
|
|
|
|
/**
|
|
* Get the response aknowledgement message sent or received by this transaction
|
|
* @return The transaction's response aknowledgement message
|
|
*/
|
|
inline const MGCPMessage* msgAck() const
|
|
{ return m_ack; }
|
|
|
|
/**
|
|
* Check if this transaction timed out
|
|
* @return True if this transaction timed out
|
|
*/
|
|
inline bool timeout() const
|
|
{ return m_timeout; }
|
|
|
|
/**
|
|
* Set the remote ACK request flag
|
|
* @param request False if remote is not required to send an ACK
|
|
*/
|
|
inline void ackRequest(bool request)
|
|
{ m_ackRequest = request; }
|
|
|
|
/**
|
|
* Get the private user data of this transaction
|
|
* @return The private user data of this transaction
|
|
*/
|
|
inline void* userData() const
|
|
{ return m_private; }
|
|
|
|
/**
|
|
* Set the private user data of this transaction
|
|
* @param data The new private user data of this transaction
|
|
*/
|
|
inline void userData(void* data)
|
|
{ m_private = data; }
|
|
|
|
/**
|
|
* Get an event from this transaction. Check timeouts
|
|
* @param time Current time in microseconds
|
|
* @return MGCPEvent pointer or 0 if none
|
|
*/
|
|
MGCPEvent* getEvent(u_int64_t time = Time());
|
|
|
|
/**
|
|
* Explicitely transmits a provisional code
|
|
* @param code Provisional response code to send, must be in range 100-199
|
|
* @param comment Optional response comment text
|
|
* @return True if the provisional response was sent
|
|
*/
|
|
bool sendProvisional(int code = 100, const char* comment = 0);
|
|
|
|
/**
|
|
* Creates and transmits a final response (code must at least 200) message if
|
|
* this is an incoming transaction
|
|
* @param code Response code to send
|
|
* @param comment Optional response comment text
|
|
* @return True if the message was queued for transmission
|
|
*/
|
|
inline bool setResponse(int code, const char* comment = 0)
|
|
{ return setResponse(new MGCPMessage(this,code,comment)); }
|
|
|
|
/**
|
|
* Creates and transmits a final response (code must at least 200) message if
|
|
* this is an incoming transaction.
|
|
* The SDP(s) will be consumed (appended to the message or destroyed)
|
|
* @param code Response code to send
|
|
* @param params Parameters to set in response, name will be set as comment
|
|
* @param sdp1 Optional SDP to be added to the response
|
|
* @param sdp2 Optional second SDP to be added to the response if the first one is not 0
|
|
* @return True if the message was queued for transmission
|
|
*/
|
|
bool setResponse(int code, const NamedList* params, MimeSdpBody* sdp1 = 0,
|
|
MimeSdpBody* sdp2 = 0);
|
|
|
|
/**
|
|
* Transmits a final response (code must at least 200)
|
|
* message if this is an incoming transaction
|
|
* @param msg The message to transmit
|
|
* @return True if the message was queued for transmission
|
|
*/
|
|
bool setResponse(MGCPMessage* msg);
|
|
|
|
protected:
|
|
/**
|
|
* Gracefully terminate this transaction. Release memory
|
|
*/
|
|
virtual void destroyed();
|
|
|
|
/**
|
|
* Consume (process) a received message, other then the initiating one
|
|
* @param msg The received message
|
|
*/
|
|
void processMessage(MGCPMessage* msg);
|
|
|
|
/**
|
|
* Check timeouts. Manage retransmissions
|
|
* @param time Current time in milliseconds
|
|
* @return MGCPEvent pointer if timeout
|
|
*/
|
|
MGCPEvent* checkTimeout(u_int64_t time);
|
|
|
|
/**
|
|
* Event termination notification
|
|
* @param event The notifier
|
|
*/
|
|
void eventTerminated(MGCPEvent* event);
|
|
|
|
/**
|
|
* Change transaction's state if the new state is a valid one
|
|
* @param newState The new state of this transaction
|
|
*/
|
|
void changeState(State newState);
|
|
|
|
/**
|
|
* Set and send the provisional response (codes between 100 and 199)
|
|
* @param code The response code
|
|
*/
|
|
void setProvisional(int code = 100);
|
|
|
|
/**
|
|
* (Re)send one the initial, provisional or final response. Change transaction's state
|
|
* @param msg The message to send
|
|
*/
|
|
void send(MGCPMessage* msg);
|
|
|
|
private:
|
|
MGCPTransaction() {} // Avoid using default constructor
|
|
// Check if received any final response. Create an event. Init timeout.
|
|
// Send a response ACK if requested by the response
|
|
MGCPEvent* checkResponse(u_int64_t time);
|
|
// Init timeout for retransmission or transaction termination
|
|
void initTimeout(u_int64_t time, bool extra);
|
|
// Remove from engine. Create event. Deref the transaction
|
|
MGCPEvent* terminate();
|
|
|
|
State m_state; // Current state
|
|
unsigned int m_id; // Transaction id
|
|
bool m_outgoing; // Transaction direction
|
|
SocketAddr m_address; // Remote andpoint's address
|
|
MGCPEngine* m_engine; // The engine owning this transaction
|
|
MGCPMessage* m_cmd; // The command that created this transaction
|
|
MGCPMessage* m_provisional; // The provisional response to the command that created this transaction
|
|
MGCPMessage* m_response; // The response to the command that created this transaction
|
|
MGCPMessage* m_ack; // The response aknowledgement message sent or received
|
|
MGCPEvent* m_lastEvent; // The last generated event
|
|
String m_endpoint; // The endpoint owning this transaction
|
|
u_int64_t m_nextRetrans; // Retransission or destroy time
|
|
unsigned int m_crtRetransInterval; // Current retransmission interval
|
|
unsigned int m_retransCount; // Remainig number of retransmissions
|
|
bool m_timeout; // Transaction timeout flag
|
|
bool m_ackRequest; // Remote is requested to send ACK
|
|
void* m_private; // Data used by this transaction's user
|
|
String m_debug; // String used to identify the transaction in debug messages
|
|
};
|
|
|
|
/**
|
|
* This class holds an endpoint id in the form "endpoint@host:port"
|
|
* @short An endpoint id
|
|
*/
|
|
class YMGCP_API MGCPEndpointId
|
|
{
|
|
public:
|
|
/**
|
|
* Constructor
|
|
*/
|
|
inline MGCPEndpointId()
|
|
: m_port(0)
|
|
{}
|
|
|
|
/**
|
|
* Constructor. Construct this endpoint id from a string
|
|
* @param src The string to construct from
|
|
*/
|
|
inline MGCPEndpointId(const String& src)
|
|
: m_port(0)
|
|
{ set(src); }
|
|
|
|
/**
|
|
* Copy constructor
|
|
* @param value Original Endpoint ID to copy
|
|
*/
|
|
inline MGCPEndpointId(const MGCPEndpointId& value)
|
|
: m_port(0)
|
|
{ set(value.user(),value.host(),value.port()); }
|
|
|
|
/**
|
|
* Constructor. Construct this endpoint id
|
|
* @param endpoint The user part of the endpoint's URI
|
|
* @param host The IP address of the endpoint's URI
|
|
* @param port The port used by the endpoint to receive data
|
|
*/
|
|
inline MGCPEndpointId(const char* endpoint, const char* host, int port)
|
|
: m_port(0)
|
|
{ set(endpoint,host,port); }
|
|
|
|
/**
|
|
* Get the full id of the endpoint
|
|
* @return The full id of the endpoint
|
|
*/
|
|
inline const String& id() const
|
|
{ return m_id; }
|
|
|
|
/**
|
|
* Get the user part of the endpoint URI
|
|
* @return The user part of the endpoint URI
|
|
*/
|
|
inline const String& user() const
|
|
{ return m_endpoint; }
|
|
|
|
/**
|
|
* Get the host part of the endpoint URI
|
|
* @return The host part of the endpoint URI
|
|
*/
|
|
inline const String& host() const
|
|
{ return m_host; }
|
|
|
|
/**
|
|
* Get the port used by this endpoint
|
|
* @return The port used by this endpoint
|
|
*/
|
|
inline int port() const
|
|
{ return m_port; }
|
|
|
|
/**
|
|
* Set the port used by this endpoint
|
|
* @param newPort The new port used by this endpoint
|
|
*/
|
|
inline void port(int newPort)
|
|
{ set(m_endpoint,m_host,newPort); }
|
|
|
|
/**
|
|
* Set this endpoint id. Convert it to lower case
|
|
* @param endpoint The user part of the endpoint's URI
|
|
* @param host The IP address of the endpoint's URI
|
|
* @param port The port used by the endpoint to receive data
|
|
*/
|
|
void set(const char* endpoint, const char* host, int port);
|
|
|
|
/**
|
|
* Set this endpoint id. Convert it to lower case
|
|
* @param src The string to construct from
|
|
*/
|
|
inline void set(const String& src) {
|
|
URI uri(src);
|
|
set(uri.getUser(),uri.getHost(),uri.getPort());
|
|
}
|
|
|
|
/**
|
|
* Check if this is a valid endpoint id as defined in RFC 3435 3.2.1.3.
|
|
* It is considerred valid if the user and host part lengths are between
|
|
* 1 and 255 and the port is not 0
|
|
* @return True if this is a valid endpoint id
|
|
*/
|
|
inline bool valid() const {
|
|
return m_endpoint && m_endpoint.length() < 256 &&
|
|
m_host && m_host.length() < 256;
|
|
}
|
|
|
|
private:
|
|
String m_id; // The complete id
|
|
String m_endpoint; // The endpoint's name inside the host
|
|
String m_host; // Host of this endpoint
|
|
int m_port; // Port used by this endpoint
|
|
};
|
|
|
|
/**
|
|
* This class holds data about a remote endpoint (id and address)
|
|
* @short Remote endpoint info class
|
|
*/
|
|
class YMGCP_API MGCPEpInfo : public MGCPEndpointId, public GenObject
|
|
{
|
|
public:
|
|
/**
|
|
* Constructor. Construct this endpoint info
|
|
* @param endpoint The endpoint part of the endpoint's id
|
|
* @param host The IP address of this endpoint
|
|
* @param port The port used to send data to this endpoint
|
|
*/
|
|
inline MGCPEpInfo(const char* endpoint, const char* host, int port)
|
|
: MGCPEndpointId(endpoint,host,port), address(AF_INET) {
|
|
address.host(host);
|
|
address.port(port);
|
|
}
|
|
|
|
/**
|
|
* Get a string representation of this object
|
|
* @return The endpoint's id
|
|
*/
|
|
virtual const String& toString() const
|
|
{ return id(); }
|
|
|
|
/**
|
|
* The IP address and port of this endpoint
|
|
*/
|
|
SocketAddr address;
|
|
|
|
/**
|
|
* An alias name of the remote endpoint, may be empty
|
|
*/
|
|
String alias;
|
|
};
|
|
|
|
/**
|
|
* This class holds a local MGCP endpoint (either gateway or call agent) along
|
|
* with its remote peer(s).
|
|
* If the engine owning this endpoint is an MGCP gateway, only 1 remote peer (Call Agent) is allowed
|
|
* @short An MGCP endpoint
|
|
*/
|
|
class YMGCP_API MGCPEndpoint : public RefObject, public MGCPEndpointId, public Mutex
|
|
{
|
|
public:
|
|
/**
|
|
* Constructor. Construct this endpoint. Append itself to the engine's list.
|
|
* The endpoint's id will be created from the received user and engine's address
|
|
* @param engine The engine owning this endpoint
|
|
* @param user The user part of the endpoint's id
|
|
* @param host The host part of the endpoint's id
|
|
* @param port The port part of the endpoint's id
|
|
*/
|
|
MGCPEndpoint(MGCPEngine* engine, const char* user, const char* host, int port);
|
|
|
|
/**
|
|
* Destructor. Remove itself from engine's list
|
|
*/
|
|
virtual ~MGCPEndpoint();
|
|
|
|
/**
|
|
* Get a string representation of this endpoint
|
|
* @return A string representation of this endpoint
|
|
*/
|
|
virtual const String& toString() const
|
|
{ return MGCPEndpointId::id(); }
|
|
|
|
/**
|
|
* Get the engine owning this endpoint
|
|
* @return The engine owning this endpoint
|
|
*/
|
|
inline MGCPEngine* engine()
|
|
{ return m_engine; }
|
|
|
|
/**
|
|
* Append info about a remote endpoint controlled by or controlling this endpoint.
|
|
* If the engine owning this endpoint is an MGCP gateway, only 1 remote peer (Call Agent) is allowed
|
|
* @param endpoint The endpoint part of the remote endpoint's id
|
|
* @param host The IP address of the remote endpoint
|
|
* @param port The port used to send data to this endpoint.
|
|
* Set to 0 to set it to the default port defined by the protocol and the
|
|
* opposite of the engine's mode
|
|
* @return Valid MGCPEpInfo pointer or 0 if the data wasn't added
|
|
*/
|
|
MGCPEpInfo* append(const char* endpoint, const char* host, int port = 0);
|
|
|
|
/**
|
|
* Clear the list or remote endpoints
|
|
*/
|
|
inline void clear()
|
|
{ lock(); m_remote.clear(); unlock(); }
|
|
|
|
/**
|
|
* Find the info object associated with a remote peer
|
|
* @param epId The remote endpoint's id to find
|
|
* @return MGCPEpInfo pointer or 0 if not found
|
|
*/
|
|
MGCPEpInfo* find(const String& epId);
|
|
|
|
/**
|
|
* Find an info object by remote peer alias
|
|
* @param alias Alias of the remote endpoint's id to find
|
|
* @return MGCPEpInfo pointer or 0 if not found
|
|
*/
|
|
MGCPEpInfo* findAlias(const String& alias);
|
|
|
|
/**
|
|
* Find the info object associated with an unique remote peer
|
|
* @return MGCPEpInfo pointer or 0 if not exactly one peer
|
|
*/
|
|
MGCPEpInfo* peer();
|
|
|
|
private:
|
|
MGCPEngine* m_engine; // The engine owning this endpoint
|
|
ObjList m_remote; // The remote endpoints
|
|
};
|
|
|
|
/**
|
|
* This class carries a copy of the message received by a transaction or a transaction state
|
|
* change notification (such as timeout or destroy)
|
|
* @short An MGCP event
|
|
*/
|
|
class YMGCP_API MGCPEvent
|
|
{
|
|
friend class MGCPTransaction;
|
|
public:
|
|
/**
|
|
* Destructor. Delete the message. Notify and deref the transaction
|
|
*/
|
|
~MGCPEvent();
|
|
|
|
/**
|
|
* Get the transaction that generated this event
|
|
* @return The transaction that generated this event
|
|
*/
|
|
inline MGCPTransaction* transaction()
|
|
{ return m_transaction; }
|
|
|
|
/**
|
|
* Get the message carried by this event
|
|
* @return The message carried by this event or 0 if none
|
|
*/
|
|
inline MGCPMessage* message() const
|
|
{ return m_message; }
|
|
|
|
protected:
|
|
/**
|
|
* Constructor. Constructs an event from a transaction
|
|
* @param trans The transaction that generated this event
|
|
* @param msg The message carried by this event, if any
|
|
*/
|
|
MGCPEvent(MGCPTransaction* trans, MGCPMessage* msg = 0);
|
|
|
|
private:
|
|
MGCPTransaction* m_transaction; // The transaction that generated this event
|
|
MGCPMessage* m_message; // The message carried by this event, if any
|
|
};
|
|
|
|
class MGCPPrivateThread;
|
|
|
|
/**
|
|
* The engine may keep gateway endpoints or call agents
|
|
* Keep the transaction list and manage it (create/delete/modify/timeout...)
|
|
* Keep a list with the endpoints it services
|
|
* Generate transaction numbers (IDs)
|
|
* Parse received messages, validate and send them to the appropriate transaction
|
|
* Send MGCP messages to remote addresses
|
|
* @short An MGCP engine
|
|
*/
|
|
class YMGCP_API MGCPEngine : public DebugEnabler, public Mutex
|
|
{
|
|
friend class MGCPPrivateThread;
|
|
friend class MGCPTransaction;
|
|
public:
|
|
/**
|
|
* Constructor. Construct the engine and, optionally, initialize it
|
|
* @param gateway Engine's mode: true if this engine is an MGCP Gateway,
|
|
* false if it's a collection of Call Agents
|
|
* @param name Optional debug name for this engine
|
|
* @param params Optional parameters used to initialize this engine
|
|
*/
|
|
MGCPEngine(bool gateway, const char* name = 0, const NamedList* params = 0);
|
|
|
|
/**
|
|
* Destructor. Clear all lists
|
|
*/
|
|
virtual ~MGCPEngine();
|
|
|
|
/**
|
|
* Check if this engine is an MGCP Gateway or a collection of Call Agents
|
|
* @return True if this engine is an MGCP Gateway, false if it's a
|
|
* collection of Call Agents
|
|
*/
|
|
inline bool gateway() const
|
|
{ return m_gateway; }
|
|
|
|
/**
|
|
* Get the IP address used by this engine to receive data
|
|
* @return The IP address used by this engine to receive data
|
|
*/
|
|
inline const SocketAddr& address() const
|
|
{ return m_address; }
|
|
|
|
/**
|
|
* Get the maximum length or received packets. This is the size of the buffer used by
|
|
* this engine to read data from the socket
|
|
* @return The maximum length or received packets
|
|
*/
|
|
inline unsigned int maxRecvPacket() const
|
|
{ return m_maxRecvPacket; }
|
|
|
|
/**
|
|
* Check if this engine is allowed to send/accept unknown commands
|
|
* @return True if this engine is allowed to send/accept unknown commands
|
|
*/
|
|
inline bool allowUnkCmd() const
|
|
{ return m_allowUnkCmd; }
|
|
|
|
/**
|
|
* Get the message retransmission interval
|
|
* @return The message retransmission interval
|
|
*/
|
|
inline unsigned int retransInterval() const
|
|
{ return m_retransInterval; }
|
|
|
|
/**
|
|
* Get the maximum number of retransmissions for a message
|
|
* @return The maximum number of retransmissions for a message
|
|
*/
|
|
inline unsigned int retransCount() const
|
|
{ return m_retransCount; }
|
|
|
|
/**
|
|
* Get the time to live after the transaction terminated gracefully
|
|
* @return The time to live after the transaction terminated gracefully
|
|
*/
|
|
inline u_int64_t extraTime() const
|
|
{ return m_extraTime; }
|
|
|
|
/**
|
|
* Check if the parser should convert received messages' parameters to lower case
|
|
* @return True if the parser should convert received messages' parameters to lower case
|
|
*/
|
|
inline bool parseParamToLower() const
|
|
{ return m_parseParamToLower; }
|
|
|
|
/**
|
|
* Check if incoming transactions would send provisional responses
|
|
* @return True if incoming transactions would send provisional responses
|
|
*/
|
|
inline bool provisional() const
|
|
{ return m_provisional; }
|
|
|
|
/**
|
|
* Get the remote ACK request flag
|
|
* @return True if remote will be requested to send an ACK
|
|
*/
|
|
inline bool ackRequest() const
|
|
{ return m_ackRequest; }
|
|
|
|
/**
|
|
* Set the remote ACK request flag
|
|
* @param request False to not request from remote to send an ACK
|
|
*/
|
|
inline void ackRequest(bool request)
|
|
{ m_ackRequest = request; }
|
|
|
|
/**
|
|
* Initialize this engine
|
|
* @param params Engine's parameters
|
|
*/
|
|
virtual void initialize(const NamedList& params);
|
|
|
|
/**
|
|
* Check if a command is known by this engine
|
|
* @param cmd The command name to check
|
|
* @return True if the given command is known by this engine
|
|
*/
|
|
inline bool knownCommand(const char* cmd)
|
|
{ Lock lock(this); return (m_knownCommands.find(cmd) != 0); }
|
|
|
|
/**
|
|
* Add a command to the list of known commands
|
|
* @param cmd The command name to add
|
|
*/
|
|
void addCommand(const char* cmd);
|
|
|
|
/**
|
|
* Append an endpoint to this engine if not already done
|
|
* @param ep The endpoint to append
|
|
*/
|
|
void attach(MGCPEndpoint* ep);
|
|
|
|
/**
|
|
* Remove an endpoint from this engine and, optionally, remove all its transactions
|
|
* @param ep The endpoint to remove
|
|
* @param del True to delete it, false to just remove it from the list
|
|
* @param delTrans True to remove all its transactions.
|
|
* Forced to true if the endpoint is deleted
|
|
*/
|
|
void detach(MGCPEndpoint* ep, bool del = false, bool delTrans = false);
|
|
|
|
/**
|
|
* Find an endpoint by its pointer
|
|
* @param ep The endpoint to find
|
|
* @return MGCPEndpoint pointer or 0 if not found
|
|
*/
|
|
MGCPEndpoint* findEp(MGCPEndpoint* ep);
|
|
|
|
/**
|
|
* Find an endpoint by its id
|
|
* @param epId The endpoint's id to find
|
|
* @return MGCPEndpoint pointer or 0 if not found
|
|
*/
|
|
MGCPEndpoint* findEp(const String& epId);
|
|
|
|
/**
|
|
* Find a transaction by its id
|
|
* @param id The id of the transaction to find
|
|
* @param outgoing The transaction direction. True for outgoing, false for incoming
|
|
* @return MGCPTransaction pointer or 0 if not found
|
|
*/
|
|
MGCPTransaction* findTrans(unsigned int id, bool outgoing);
|
|
|
|
/**
|
|
* Generate a new id for an outgoing transaction
|
|
* @return An id for an outgoing transaction
|
|
*/
|
|
unsigned int getNextId();
|
|
|
|
/**
|
|
* Send a command message. Create a transaction for it.
|
|
* The method will fail if the message is not a valid one or isn't a valid command
|
|
* @param cmd The message containig the command
|
|
* @param address The destination IP address
|
|
* @return MGCPTransaction pointer or 0 if failed to create a transaction
|
|
*/
|
|
MGCPTransaction* sendCommand(MGCPMessage* cmd, const SocketAddr& address);
|
|
|
|
/**
|
|
* Read data from the socket. Parse and process the received message
|
|
* @param buffer Buffer used for read operation. The buffer must be large enough
|
|
* to keep the maximum packet length returned by @ref maxRecvPacket()
|
|
* @param addr The sender's address if received any data
|
|
* @return True if received any data (a message was successfully parsed)
|
|
*/
|
|
bool receive(unsigned char* buffer, SocketAddr& addr);
|
|
|
|
/**
|
|
* Try to get an event from a transaction.
|
|
* If the event contains an unknown command and this engine is not allowed
|
|
* to process such commands, calls the @ref returnEvent() method, otherwise,
|
|
* calls the @ref processEvent() method
|
|
* @param time Current time in microseconds
|
|
* @return True if an event was processed
|
|
*/
|
|
bool process(u_int64_t time = Time());
|
|
|
|
/**
|
|
* Repeatedly calls @ref receive() until the calling thread terminates
|
|
*/
|
|
void runReceive();
|
|
|
|
/**
|
|
* Repeatedly calls @ref process() until the calling thread terminates
|
|
*/
|
|
void runProcess();
|
|
|
|
/**
|
|
* Try to get an event from a transaction
|
|
* @param time Current time in microseconds
|
|
* @return MGCPEvent pointer or 0 if none
|
|
*/
|
|
MGCPEvent* getEvent(u_int64_t time = Time());
|
|
|
|
/**
|
|
* Process an event generated by a transaction. Descendants must override this
|
|
* method if they want to process events. By default it calls the version
|
|
* of processEvent that accepts separate parameters of event
|
|
* @param event The event to process
|
|
* @return True if the event was processed. If the event carry a received
|
|
* command and it's not processed the transaction will receive an 'unknown command' response
|
|
*/
|
|
virtual bool processEvent(MGCPEvent* event);
|
|
|
|
/**
|
|
* Process an event generated by a transaction. Descendants must override this
|
|
* method if they want to process events
|
|
* @param trans Pointer to the transaction that generated the event
|
|
* @param msg MGCP message of the event, may be NULL
|
|
* @param data User data that is stored in transaction, may be NULL
|
|
* @return True if the event was processed. If the event carry a received
|
|
* command and it's not processed the transaction will receive an 'unknown command' response
|
|
*/
|
|
virtual bool processEvent(MGCPTransaction* trans, MGCPMessage* msg, void* data);
|
|
|
|
/**
|
|
* Returns an unprocessed event to this engine to be deleted.
|
|
* Incoming transactions will be responded. Unknown commands will receive a
|
|
* 504 Unknown Command response, the others will receive a 507 Unsupported Functionality one
|
|
* @param event The event to return
|
|
*/
|
|
void returnEvent(MGCPEvent* event);
|
|
|
|
/**
|
|
* Terminate all transactions. Cancel all private threads if any and
|
|
* wait for them to terminate
|
|
* @param gracefully If true, all incoming transaction will be responded and private
|
|
* threads will be gently cancelled. If false, all transactions will be deleted and
|
|
* threads will be cancelled the hard way
|
|
* @param text Optional text to be sent with the response code of the incoming
|
|
* transactions on gracefully cleanup
|
|
*/
|
|
void cleanup(bool gracefully = true, const char* text = "Shutdown");
|
|
|
|
/**
|
|
* Get the default port defined by the protocol
|
|
* @param gateway True to get the default Gateway port,
|
|
* false to get the default port for the Call Agent
|
|
* @return The default port defined by the protocol
|
|
*/
|
|
static inline int defaultPort(bool gateway)
|
|
{ return gateway ? 2427 : 2727; }
|
|
|
|
/**
|
|
* The list of commands defined in RFC 3435
|
|
*/
|
|
static TokenDict mgcp_commands[];
|
|
|
|
/**
|
|
* The list of known responses defined in RFC 3435 2.4
|
|
*/
|
|
static TokenDict mgcp_responses[];
|
|
|
|
/**
|
|
* The list of known reason codes defined in RFC 3435 2.5.
|
|
* Reason codes are used by the gateway when deleting a connection to
|
|
* inform the Call Agent about the reason for deleting the connection.
|
|
* They may also be used in a RestartInProgress command to inform the
|
|
* Call Agent of the reason for the RestartInProgress
|
|
*/
|
|
static TokenDict mgcp_reasons[];
|
|
|
|
protected:
|
|
/**
|
|
* Send a string buffer through the socket
|
|
* @param msg The buffer to send
|
|
* @param address The destination IP address
|
|
* @return False if the operation failed
|
|
*/
|
|
bool sendData(const String& msg, const SocketAddr& address);
|
|
|
|
/**
|
|
* Append a transaction to the list
|
|
* @param trans The transaction to append
|
|
*/
|
|
void appendTrans(MGCPTransaction* trans);
|
|
|
|
/**
|
|
* Remove a transaction from the list
|
|
* @param trans The transaction to remove
|
|
* @param del True to delete it, false to just remove it from list
|
|
*/
|
|
void removeTrans(MGCPTransaction* trans, bool del);
|
|
|
|
/**
|
|
* The list of endpoints attached to this engine
|
|
*/
|
|
ObjList m_endpoints;
|
|
|
|
/**
|
|
* The transaction list
|
|
*/
|
|
ObjList m_transactions;
|
|
|
|
private:
|
|
// Append a private thread to the list
|
|
void appendThread(MGCPPrivateThread* thread);
|
|
// Remove private thread from the list without deleting it
|
|
void removeThread(MGCPPrivateThread* thread);
|
|
// Process ACK received with a message or response
|
|
// Return a list of ack'd transactions or 0 if the parameter is incorrect
|
|
unsigned int* decodeAck(const String& param, unsigned int & count);
|
|
|
|
bool m_gateway; // True if this engine is an MGCP gateway, false if call agent
|
|
bool m_initialized; // True if the engine was already initialized
|
|
unsigned int m_nextId; // Next outgoing transaction id
|
|
Socket m_socket; // The socket used to send/receive data
|
|
SocketAddr m_address; // The IP address used by this engine
|
|
unsigned int m_maxRecvPacket; // The maximum length or received packets
|
|
unsigned char* m_recvBuf; // Receiving buffer
|
|
bool m_allowUnkCmd; // Allow this engine to send/accept unknown commands
|
|
unsigned int m_retransInterval; // Message retransmission interval
|
|
unsigned int m_retransCount; // Maximum number of retransmissions for a message
|
|
u_int64_t m_extraTime; // Time to live after the transaction terminated gracefully
|
|
bool m_parseParamToLower; // Convert received messages' params to lower case
|
|
bool m_provisional; // Send provisional responses flag
|
|
bool m_ackRequest; // Remote is requested to send ACK
|
|
ObjList m_knownCommands; // The list of known commands
|
|
ObjList m_threads;
|
|
};
|
|
|
|
}
|
|
|
|
#endif /* __YATEMGCP_H */
|
|
|
|
/* vi: set ts=8 sw=4 sts=4 noet: */
|