pjproject/pjsip/include/pjsip/sip_transport.h

1515 lines
47 KiB
C

/* $Id$ */
/*
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __PJSIP_SIP_TRANSPORT_H__
#define __PJSIP_SIP_TRANSPORT_H__
/**
* @file sip_transport.h
* @brief SIP Transport
*/
#include <pjsip/sip_msg.h>
#include <pjsip/sip_parser.h>
#include <pjsip/sip_resolve.h>
#include <pj/sock.h>
#include <pj/list.h>
#include <pj/ioqueue.h>
#include <pj/timer.h>
PJ_BEGIN_DECL
/**
* @defgroup PJSIP_TRANSPORT Transport
* @ingroup PJSIP_CORE
* @brief This is the transport framework.
*
* The transport framework is fully extensible. Please see
* <A HREF="/docs.htm">PJSIP Developer's Guide</A> PDF
* document for more information.
*
* Application MUST register at least one transport to PJSIP before any
* messages can be sent or received. Please see @ref PJSIP_TRANSPORT_UDP
* on how to create/register UDP transport to the transport framework.
*
* @{
*/
/*****************************************************************************
*
* GENERAL TRANSPORT (NAMES, TYPES, ETC.)
*
*****************************************************************************/
/*
* Forward declaration for transport factory (since it is referenced by
* the transport factory itself).
*/
typedef struct pjsip_tpfactory pjsip_tpfactory;
/**
* Flags for SIP transports.
*/
enum pjsip_transport_flags_e
{
PJSIP_TRANSPORT_RELIABLE = 1, /**< Transport is reliable. */
PJSIP_TRANSPORT_SECURE = 2, /**< Transport is secure. */
PJSIP_TRANSPORT_DATAGRAM = 4 /**< Datagram based transport.
(it's also assumed to be
connectionless) */
};
/**
* Check if transport tp is reliable.
*/
#define PJSIP_TRANSPORT_IS_RELIABLE(tp) \
((tp)->flag & PJSIP_TRANSPORT_RELIABLE)
/**
* Check if transport tp is secure.
*/
#define PJSIP_TRANSPORT_IS_SECURE(tp) \
((tp)->flag & PJSIP_TRANSPORT_SECURE)
/**
* Register new transport type to PJSIP. The PJSIP transport framework
* contains the info for some standard transports, as declared by
* #pjsip_transport_type_e. Application may use non-standard transport
* with PJSIP, but before it does so, it must register the information
* about the new transport type to PJSIP by calling this function.
*
* @param tp_flag The flags describing characteristics of this
* transport type.
* @param tp_name Transport type name.
* @param def_port Default port to be used for the transport.
* @param p_tp_type On successful registration, it will be filled with
* the registered type. This argument is optional.
*
* @return PJ_SUCCESS if registration is successful, or
* PJSIP_ETYPEEXISTS if the same transport type has
* already been registered.
*/
PJ_DECL(pj_status_t) pjsip_transport_register_type(unsigned tp_flag,
const char *tp_name,
int def_port,
int *p_tp_type);
/**
* Get the transport type from the transport name.
*
* @param name Transport name, such as "TCP", or "UDP".
*
* @return The transport type, or PJSIP_TRANSPORT_UNSPECIFIED if
* the name is not recognized as the name of supported
* transport.
*/
PJ_DECL(pjsip_transport_type_e)
pjsip_transport_get_type_from_name(const pj_str_t *name);
/**
* Get the transport type for the specified flags.
*
* @param flag The transport flag.
*
* @return Transport type.
*/
PJ_DECL(pjsip_transport_type_e)
pjsip_transport_get_type_from_flag(unsigned flag);
/**
* Get the socket address family of a given transport type.
*
* @param type Transport type.
*
* @return Transport type.
*/
PJ_DECL(int) pjsip_transport_type_get_af(pjsip_transport_type_e type);
/**
* Get transport flag from type.
*
* @param type Transport type.
*
* @return Transport flags.
*/
PJ_DECL(unsigned)
pjsip_transport_get_flag_from_type( pjsip_transport_type_e type );
/**
* Get the default SIP port number for the specified type.
*
* @param type Transport type.
*
* @return The port number, which is the default SIP port number for
* the specified type.
*/
PJ_DECL(int)
pjsip_transport_get_default_port_for_type(pjsip_transport_type_e type);
/**
* Get transport type name.
*
* @param t Transport type.
*
* @return Transport name.
*/
PJ_DECL(const char*) pjsip_transport_get_type_name(pjsip_transport_type_e t);
/**
* Get longer description for the specified transport type.
*
* @param t Transport type.
*
* @return Transport description.
*/
PJ_DECL(const char*) pjsip_transport_get_type_desc(pjsip_transport_type_e t);
/*****************************************************************************
*
* TRANSPORT SELECTOR.
*
*****************************************************************************/
/**
* This structure describes the type of data in pjsip_tpselector.
*/
typedef enum pjsip_tpselector_type
{
/** Transport is not specified. */
PJSIP_TPSELECTOR_NONE,
/** Use the specific transport to send request. */
PJSIP_TPSELECTOR_TRANSPORT,
/** Use the specific listener to send request. */
PJSIP_TPSELECTOR_LISTENER,
} pjsip_tpselector_type;
/**
* This structure describes the transport/listener preference to be used
* when sending outgoing requests.
*
* Normally transport will be selected automatically according to rules about
* sending requests. But some applications (such as proxies or B2BUAs) may
* want to explicitly use specific transport to send requests, for example
* when they want to make sure that outgoing request should go from a specific
* network interface.
*
* The pjsip_tpselector structure is used for that purpose, i.e. to allow
* application specificly request that a particular transport/listener
* should be used to send request. This structure is used when calling
* pjsip_tsx_set_transport() and pjsip_dlg_set_transport().
*/
typedef struct pjsip_tpselector
{
/** The type of data in the union */
pjsip_tpselector_type type;
/** Union representing the transport/listener criteria to be used. */
union {
pjsip_transport *transport;
pjsip_tpfactory *listener;
void *ptr;
} u;
} pjsip_tpselector;
/**
* Add transport/listener reference in the selector to prevent the specified
* transport/listener from being destroyed while application still has
* reference to it.
*
* @param sel The transport selector.
*/
PJ_DECL(void) pjsip_tpselector_add_ref(pjsip_tpselector *sel);
/**
* Decrement transport/listener reference in the selector.
* @param sel The transport selector
*/
PJ_DECL(void) pjsip_tpselector_dec_ref(pjsip_tpselector *sel);
/*****************************************************************************
*
* RECEIVE DATA BUFFER.
*
*****************************************************************************/
/**
* A customized ioqueue async operation key which is used by transport
* to locate rdata when a pending read operation completes.
*/
typedef struct pjsip_rx_data_op_key
{
pj_ioqueue_op_key_t op_key; /**< ioqueue op_key. */
pjsip_rx_data *rdata; /**< rdata associated with this */
} pjsip_rx_data_op_key;
/**
* Incoming message buffer.
* This structure keep all the information regarding the received message. This
* buffer lifetime is only very short, normally after the transaction has been
* called, this buffer will be deleted/recycled. So care must be taken when
* allocating storage from the pool of this buffer.
*/
struct pjsip_rx_data
{
/**
* tp_info is part of rdata that remains static for the duration of the
* buffer. It is initialized when the buffer was created by transport.
*/
struct
{
/** Memory pool for this buffer. */
pj_pool_t *pool;
/** The transport object which received this packet. */
pjsip_transport *transport;
/** Other transport specific data to be attached to this buffer. */
void *tp_data;
/** Ioqueue key. */
pjsip_rx_data_op_key op_key;
} tp_info;
/**
* pkt_info is initialized by transport when it receives an incoming
* packet.
*/
struct
{
/** Time when the message was received. */
pj_time_val timestamp;
/** Pointer to the original packet. */
char packet[PJSIP_MAX_PKT_LEN];
/** Zero termination for the packet. */
pj_uint32_t zero;
/** The length of the packet received. */
pj_ssize_t len;
/** The source address from which the packet was received. */
pj_sockaddr src_addr;
/** The length of the source address. */
int src_addr_len;
/** The IP source address string (NULL terminated). */
char src_name[PJ_INET6_ADDRSTRLEN];
/** The IP source port number. */
int src_port;
} pkt_info;
/**
* msg_info is initialized by transport mgr (tpmgr) before this buffer
* is passed to endpoint.
*/
struct
{
/** Start of msg buffer. */
char *msg_buf;
/** Length fo message. */
int len;
/** The parsed message, if any. */
pjsip_msg *msg;
/** Short description about the message.
* Application should use #pjsip_rx_data_get_info() instead.
*/
char *info;
/** The Call-ID header as found in the message. */
pjsip_cid_hdr *cid;
/** The From header as found in the message. */
pjsip_from_hdr *from;
/** The To header as found in the message. */
pjsip_to_hdr *to;
/** The topmost Via header as found in the message. */
pjsip_via_hdr *via;
/** The CSeq header as found in the message. */
pjsip_cseq_hdr *cseq;
/** Max forwards header. */
pjsip_max_fwd_hdr *max_fwd;
/** The first route header. */
pjsip_route_hdr *route;
/** The first record-route header. */
pjsip_rr_hdr *record_route;
/** Content-type header. */
pjsip_ctype_hdr *ctype;
/** Content-length header. */
pjsip_clen_hdr *clen;
/** "Require" header containing aggregates of all Require
* headers found in the message, or NULL.
*/
pjsip_require_hdr *require;
/** "Supported" header containing aggregates of all Supported
* headers found in the message, or NULL.
*/
pjsip_supported_hdr *supported;
/** The list of error generated by the parser when parsing
this message.
*/
pjsip_parser_err_report parse_err;
} msg_info;
/**
* endpt_info is initialized by endpoint after this buffer reaches
* endpoint.
*/
struct
{
/**
* Data attached by modules to this message.
*/
void *mod_data[PJSIP_MAX_MODULE];
} endpt_info;
};
/**
* Get printable information about the message in the rdata.
*
* @param rdata The receive data buffer.
*
* @return Printable information.
*/
PJ_DECL(char*) pjsip_rx_data_get_info(pjsip_rx_data *rdata);
/**
* Clone pjsip_rx_data. This will duplicate the contents of
* pjsip_rx_data and add reference count to the transport.
* Once application has finished using the cloned pjsip_rx_data,
* it must release it by calling #pjsip_rx_data_free_cloned().
*
* By default (if flags is set to zero), this function copies the
* transport pointer in \a tp_info, duplicates the \a pkt_info,
* perform deep clone of the \a msg_info parts of the rdata, and
* fills the \a endpt_info (i.e. the \a mod_data) with zeros.
*
* @param src The source to be cloned.
* @param flags Optional flags. Must be zero for now.
* @param p_rdata Pointer to receive the cloned rdata.
*
* @return PJ_SUCCESS on success or the appropriate error.
*/
PJ_DECL(pj_status_t) pjsip_rx_data_clone(const pjsip_rx_data *src,
unsigned flags,
pjsip_rx_data **p_rdata);
/**
* Free cloned pjsip_rx_data. This function must be and must only
* be called for a cloned pjsip_rx_data. Specifically, it must NOT
* be called for the original pjsip_rx_data that is returned by
* transports.
*
* This function will free the memory used by the pjsip_rx_data and
* decrement the transport reference counter.
*
* @param rdata The receive data buffer.
*
* @return PJ_SUCCESS on success or the appropriate error.
*/
PJ_DECL(pj_status_t) pjsip_rx_data_free_cloned(pjsip_rx_data *rdata);
/*****************************************************************************
*
* TRANSMIT DATA BUFFER MANIPULATION.
*
*****************************************************************************/
/** Customized ioqueue async operation key, used by transport to keep
* callback parameters.
*/
typedef struct pjsip_tx_data_op_key
{
/** ioqueue pending operation key. */
pj_ioqueue_op_key_t key;
/** Transmit data associated with this key. */
pjsip_tx_data *tdata;
/** Arbitrary token (attached by transport) */
void *token;
/** Callback to be called when pending transmit operation has
completed.
*/
void (*callback)(pjsip_transport*,void*,pj_ssize_t);
} pjsip_tx_data_op_key;
/**
* Data structure for sending outgoing message. Application normally creates
* this buffer by calling #pjsip_endpt_create_tdata.
*
* The lifetime of this buffer is controlled by the reference counter in this
* structure, which is manipulated by calling #pjsip_tx_data_add_ref and
* #pjsip_tx_data_dec_ref. When the reference counter has reached zero, then
* this buffer will be destroyed.
*
* A transaction object normally will add reference counter to this buffer
* when application calls #pjsip_tsx_send_msg, because it needs to keep the
* message for retransmission. The transaction will release the reference
* counter once its state has reached final state.
*/
struct pjsip_tx_data
{
/** This is for transmission queue; it's managed by transports. */
PJ_DECL_LIST_MEMBER(struct pjsip_tx_data);
/** Memory pool for this buffer. */
pj_pool_t *pool;
/** A name to identify this buffer. */
char obj_name[PJ_MAX_OBJ_NAME];
/** Short information describing this buffer and the message in it.
* Application should use #pjsip_tx_data_get_info() instead of
* directly accessing this member.
*/
char *info;
/** For response message, this contains the reference to timestamp when
* the original request message was received. The value of this field
* is set when application creates response message to a request by
* calling #pjsip_endpt_create_response.
*/
pj_time_val rx_timestamp;
/** The transport manager for this buffer. */
pjsip_tpmgr *mgr;
/** Ioqueue asynchronous operation key. */
pjsip_tx_data_op_key op_key;
/** Lock object. */
pj_lock_t *lock;
/** The message in this buffer. */
pjsip_msg *msg;
/** Strict route header saved by #pjsip_process_route_set(), to be
* restored by #pjsip_restore_strict_route_set().
*/
pjsip_route_hdr *saved_strict_route;
/** Buffer to the printed text representation of the message. When the
* content of this buffer is set, then the transport will send the content
* of this buffer instead of re-printing the message structure. If the
* message structure has changed, then application must invalidate this
* buffer by calling #pjsip_tx_data_invalidate_msg.
*/
pjsip_buffer buf;
/** Reference counter. */
pj_atomic_t *ref_cnt;
/** Being processed by transport? */
int is_pending;
/** Transport manager internal. */
void *token;
/** Callback to be called when this tx_data has been transmitted. */
void (*cb)(void*, pjsip_tx_data*, pj_ssize_t);
/** Destination information, to be used to determine the network address
* of the message. For a request, this information is initialized when
* the request is sent with #pjsip_endpt_send_request_stateless() and
* network address is resolved. For CANCEL request, this information
* will be copied from the original INVITE to make sure that the CANCEL
* request goes to the same physical network address as the INVITE
* request.
*/
struct
{
/** Server name.
*/
pj_str_t name;
/** Server addresses resolved.
*/
pjsip_server_addresses addr;
/** Current server address being tried.
*/
unsigned cur_addr;
} dest_info;
/** Transport information, only valid during on_tx_request() and
* on_tx_response() callback.
*/
struct
{
pjsip_transport *transport; /**< Transport being used. */
pj_sockaddr dst_addr; /**< Destination address. */
int dst_addr_len; /**< Length of address. */
char dst_name[PJ_INET6_ADDRSTRLEN]; /**< Destination address. */
int dst_port; /**< Destination port. */
} tp_info;
/**
* Transport selector, to specify which transport to be used.
* The value here must be set with pjsip_tx_data_set_transport(),
* to allow reference counter to be set properly.
*/
pjsip_tpselector tp_sel;
/**
* Special flag to indicate that this transmit data is a request that has
* been updated with proper authentication response and is ready to be
* sent for retry.
*/
pj_bool_t auth_retry;
/**
* Arbitrary data attached by PJSIP modules.
*/
void *mod_data[PJSIP_MAX_MODULE];
/**
* If via_addr is set, it will be used as the "sent-by" field of the
* Via header for outgoing requests as long as the request uses via_tp
* transport. Normally application should not use or access these fields.
*/
pjsip_host_port via_addr; /**< Via address. */
const void *via_tp; /**< Via transport. */
};
/**
* Create a new, blank transmit buffer. The reference count is initialized
* to zero.
*
* @param mgr The transport manager.
* @param tdata Pointer to receive transmit data.
*
* @return PJ_SUCCESS, or the appropriate error code.
*
* @see pjsip_endpt_create_tdata
*/
PJ_DECL(pj_status_t) pjsip_tx_data_create( pjsip_tpmgr *mgr,
pjsip_tx_data **tdata );
/**
* Add reference counter to the transmit buffer. The reference counter controls
* the life time of the buffer, ie. when the counter reaches zero, then it
* will be destroyed.
*
* @param tdata The transmit buffer.
*/
PJ_DECL(void) pjsip_tx_data_add_ref( pjsip_tx_data *tdata );
/**
* Decrement reference counter of the transmit buffer.
* When the transmit buffer is no longer used, it will be destroyed and
* caller is informed with PJSIP_EBUFDESTROYED return status.
*
* @param tdata The transmit buffer data.
* @return This function will always succeeded eventhough the return
* status is non-zero. A status PJSIP_EBUFDESTROYED will be
* returned to inform that buffer is destroyed.
*/
PJ_DECL(pj_status_t) pjsip_tx_data_dec_ref( pjsip_tx_data *tdata );
/**
* Print the SIP message to transmit data buffer's internal buffer. This
* may allocate memory for the buffer, if the buffer has not been allocated
* yet, and encode the SIP message to that buffer.
*
* @param tdata The transmit buffer.
*
* @return PJ_SUCCESS on success of the appropriate error code.
*/
PJ_DECL(pj_status_t) pjsip_tx_data_encode(pjsip_tx_data *tdata);
/**
* Check if transmit data buffer contains a valid message.
*
* @param tdata The transmit buffer.
* @return Non-zero (PJ_TRUE) if buffer contains a valid message.
*/
PJ_DECL(pj_bool_t) pjsip_tx_data_is_valid( pjsip_tx_data *tdata );
/**
* Invalidate the print buffer to force message to be re-printed. Call
* when the message has changed after it has been printed to buffer. The
* message is printed to buffer normally by transport when it is about to be
* sent to the wire. Subsequent sending of the message will not cause
* the message to be re-printed, unless application invalidates the buffer
* by calling this function.
*
* @param tdata The transmit buffer.
*/
PJ_DECL(void) pjsip_tx_data_invalidate_msg( pjsip_tx_data *tdata );
/**
* Get short printable info about the transmit data. This will normally return
* short information about the message.
*
* @param tdata The transmit buffer.
*
* @return Null terminated info string.
*/
PJ_DECL(char*) pjsip_tx_data_get_info( pjsip_tx_data *tdata );
/**
* Set the explicit transport to be used when sending this transmit data.
* Application should not need to call this function, but rather use
* pjsip_tsx_set_transport() and pjsip_dlg_set_transport() instead (which
* will call this function).
*
* @param tdata The transmit buffer.
* @param sel Transport selector.
*
* @return PJ_SUCCESS on success.
*/
PJ_DECL(pj_status_t) pjsip_tx_data_set_transport(pjsip_tx_data *tdata,
const pjsip_tpselector *sel);
/*****************************************************************************
*
* TRANSPORT
*
*****************************************************************************/
/**
* Type of callback to receive transport operation status.
*/
typedef void (*pjsip_transport_callback)(pjsip_transport *tp, void *token,
pj_ssize_t sent_bytes);
/**
* This structure describes transport key to be registered to hash table.
*/
typedef struct pjsip_transport_key
{
/**
* Transport type.
*/
long type;
/**
* Destination address.
*/
pj_sockaddr rem_addr;
} pjsip_transport_key;
/**
* Enumeration of transport direction types.
*/
typedef enum pjsip_transport_dir
{
PJSIP_TP_DIR_NONE, /**< Direction not set, normally used by
connectionless transports such as
UDP transport. */
PJSIP_TP_DIR_OUTGOING, /**< Outgoing connection or client mode,
this is only for connection-oriented
transports. */
PJSIP_TP_DIR_INCOMING, /**< Incoming connection or server mode,
this is only for connection-oriented
transports. */
} pjsip_transport_dir;
/**
* This structure represent the "public" interface of a SIP transport.
* Applications normally extend this structure to include transport
* specific members.
*/
struct pjsip_transport
{
char obj_name[PJ_MAX_OBJ_NAME]; /**< Name. */
pj_pool_t *pool; /**< Pool used by transport. */
pj_atomic_t *ref_cnt; /**< Reference counter. */
pj_lock_t *lock; /**< Lock object. */
pj_bool_t tracing; /**< Tracing enabled? */
pj_bool_t is_shutdown; /**< Being shutdown? */
pj_bool_t is_destroying; /**< Destroy in progress? */
/** Key for indexing this transport in hash table. */
pjsip_transport_key key;
char *type_name; /**< Type name. */
unsigned flag; /**< #pjsip_transport_flags_e */
char *info; /**< Transport info/description.*/
int addr_len; /**< Length of addresses. */
pj_sockaddr local_addr; /**< Bound address. */
pjsip_host_port local_name; /**< Published name (eg. STUN). */
pjsip_host_port remote_name; /**< Remote address name. */
pjsip_transport_dir dir; /**< Connection direction. */
pjsip_endpoint *endpt; /**< Endpoint instance. */
pjsip_tpmgr *tpmgr; /**< Transport manager. */
pj_timer_entry idle_timer; /**< Timer when ref cnt is zero.*/
void *data; /**< Internal transport data. */
/**
* Function to be called by transport manager to send SIP message.
*
* @param transport The transport to send the message.
* @param packet The buffer to send.
* @param length The length of the buffer to send.
* @param op_key Completion token, which will be supplied to
* caller when pending send operation completes.
* @param rem_addr The remote destination address.
* @param addr_len Size of remote address.
* @param callback If supplied, the callback will be called
* once a pending transmission has completed. If
* the function completes immediately (i.e. return
* code is not PJ_EPENDING), the callback will not
* be called.
*
* @return Should return PJ_SUCCESS only if data has been
* succesfully queued to operating system for
* transmission. Otherwise it may return PJ_EPENDING
* if the underlying transport can not send the
* data immediately and will send it later, which in
* this case caller doesn't have to do anything
* except wait the calback to be called, if it
* supplies one.
* Other return values indicate the error code.
*/
pj_status_t (*send_msg)(pjsip_transport *transport,
pjsip_tx_data *tdata,
const pj_sockaddr_t *rem_addr,
int addr_len,
void *token,
pjsip_transport_callback callback);
/**
* Instruct the transport to initiate graceful shutdown procedure.
* After all objects release their reference to this transport,
* the transport will be deleted.
*
* Note that application MUST use #pjsip_transport_shutdown() instead.
*
* @param transport The transport.
*
* @return PJ_SUCCESS on success.
*/
pj_status_t (*do_shutdown)(pjsip_transport *transport);
/**
* Forcefully destroy this transport regardless whether there are
* objects that currently use this transport. This function should only
* be called by transport manager or other internal objects (such as the
* transport itself) who know what they're doing. Application should use
* #pjsip_transport_shutdown() instead.
*
* @param transport The transport.
*
* @return PJ_SUCCESS on success.
*/
pj_status_t (*destroy)(pjsip_transport *transport);
/*
* Application may extend this structure..
*/
};
/**
* Register a transport instance to the transport manager. This function
* is normally called by the transport instance when it is created
* by application.
*
* @param mgr The transport manager.
* @param tp The new transport to be registered.
*
* @return PJ_SUCCESS on success.
*/
PJ_DECL(pj_status_t) pjsip_transport_register( pjsip_tpmgr *mgr,
pjsip_transport *tp );
/**
* Start graceful shutdown procedure for this transport. After graceful
* shutdown has been initiated, no new reference can be obtained for
* the transport. However, existing objects that currently uses the
* transport may still use this transport to send and receive packets.
*
* After all objects release their reference to this transport,
* the transport will be destroyed immediately.
*
* @param tp The transport.
*
* @return PJ_SUCCESS on success.
*/
PJ_DECL(pj_status_t) pjsip_transport_shutdown(pjsip_transport *tp);
/**
* Destroy a transport when there is no object currently uses the transport.
* This function is normally called internally by transport manager or the
* transport itself. Application should use #pjsip_transport_shutdown()
* instead.
*
* @param tp The transport instance.
*
* @return PJ_SUCCESS on success or the appropriate error code.
* Some of possible errors are PJSIP_EBUSY if the
* transport's reference counter is not zero.
*/
PJ_DECL(pj_status_t) pjsip_transport_destroy( pjsip_transport *tp);
/**
* Add reference counter to the specified transport. Any objects that wishes
* to keep the reference of the transport MUST increment the transport's
* reference counter to prevent it from being destroyed.
*
* @param tp The transport instance.
*
* @return PJ_SUCCESS on success or the appropriate error code.
*/
PJ_DECL(pj_status_t) pjsip_transport_add_ref( pjsip_transport *tp );
/**
* Decrement reference counter of the specified transport. When an object no
* longer want to keep the reference to the transport, it must decrement the
* reference counter. When the reference counter of the transport reaches
* zero, the transport manager will start the idle timer to destroy the
* transport if no objects acquire the reference counter during the idle
* interval.
*
* @param tp The transport instance.
*
* @return PJ_SUCCESS on success.
*/
PJ_DECL(pj_status_t) pjsip_transport_dec_ref( pjsip_transport *tp );
/**
* This function is called by transport instances to report an incoming
* packet to the transport manager. The transport manager then would try to
* parse all SIP messages in the packet, and for each parsed SIP message, it
* would report the message to the SIP endpoint (#pjsip_endpoint).
*
* @param mgr The transport manager instance.
* @param rdata The receive data buffer containing the packet. The
* transport MUST fully initialize tp_info and pkt_info
* member of the rdata.
*
* @return The number of bytes successfully processed from the
* packet. If the transport is datagram oriented, the
* value will be equal to the size of the packet. For
* stream oriented transport (e.g. TCP, TLS), the value
* returned may be less than the packet size, if
* partial message is received. The transport then MUST
* keep the remainder part and report it again to
* this function once more data/packet is received.
*/
PJ_DECL(pj_ssize_t) pjsip_tpmgr_receive_packet(pjsip_tpmgr *mgr,
pjsip_rx_data *rdata);
/*****************************************************************************
*
* TRANSPORT FACTORY
*
*****************************************************************************/
/**
* A transport factory is normally used for connection oriented transports
* (such as TCP or TLS) to create instances of transports. It registers
* a new transport type to the transport manager, and the transport manager
* would ask the factory to create a transport instance when it received
* command from application to send a SIP message using the specified
* transport type.
*/
struct pjsip_tpfactory
{
/** This list is managed by transport manager. */
PJ_DECL_LIST_MEMBER(struct pjsip_tpfactory);
char obj_name[PJ_MAX_OBJ_NAME]; /**< Name. */
pj_pool_t *pool; /**< Owned memory pool. */
pj_lock_t *lock; /**< Lock object. */
pjsip_transport_type_e type; /**< Transport type. */
char *type_name; /**< Type string name. */
unsigned flag; /**< Transport flag. */
pj_sockaddr local_addr; /**< Bound address. */
pjsip_host_port addr_name; /**< Published name. */
/**
* Create new outbound connection suitable for sending SIP message
* to specified remote address.
* Note that the factory is responsible for both creating the
* transport and registering it to the transport manager.
*/
pj_status_t (*create_transport)(pjsip_tpfactory *factory,
pjsip_tpmgr *mgr,
pjsip_endpoint *endpt,
const pj_sockaddr *rem_addr,
int addr_len,
pjsip_transport **transport);
/**
* Create new outbound connection suitable for sending SIP message
* to specified remote address by also considering outgoing SIP
* message data.
* Note that the factory is responsible for both creating the
* transport and registering it to the transport manager.
*/
pj_status_t (*create_transport2)(pjsip_tpfactory *factory,
pjsip_tpmgr *mgr,
pjsip_endpoint *endpt,
const pj_sockaddr *rem_addr,
int addr_len,
pjsip_tx_data *tdata,
pjsip_transport **transport);
/**
* Destroy the listener.
*/
pj_status_t (*destroy)(pjsip_tpfactory *factory);
/*
* Application may extend this structure..
*/
};
/**
* Register a transport factory.
*
* @param mgr The transport manager.
* @param tpf Transport factory.
*
* @return PJ_SUCCESS if listener was successfully created.
*/
PJ_DECL(pj_status_t) pjsip_tpmgr_register_tpfactory(pjsip_tpmgr *mgr,
pjsip_tpfactory *tpf);
/**
* Unregister factory.
*
* @param mgr The transport manager.
* @param tpf Transport factory.
*
* @return PJ_SUCCESS is sucessfully unregistered.
*/
PJ_DECL(pj_status_t) pjsip_tpmgr_unregister_tpfactory(pjsip_tpmgr *mgr,
pjsip_tpfactory *tpf);
/*****************************************************************************
*
* TRANSPORT MANAGER
*
*****************************************************************************/
/**
* Type of callback to be called when transport manager receives incoming
* SIP message.
*
* @param ep Endpoint.
* @param status Receiption status.
* @param rd Received packet.
*/
typedef void (*pjsip_rx_callback)(pjsip_endpoint *ep, pj_status_t status,
pjsip_rx_data *rd);
/**
* Type of callback to be called before transport manager is about
* to transmit SIP message.
*
* @param ep Endpoint.
* @param td Transmit data.
*/
typedef pj_status_t (*pjsip_tx_callback)(pjsip_endpoint *ep, pjsip_tx_data*td);
/**
* Create a transport manager. Normally application doesn't need to call
* this function directly, since a transport manager will be created and
* destroyed automatically by the SIP endpoint.
*
* @param pool Pool.
* @param endpt Endpoint instance.
* @param rx_cb Callback to receive incoming message.
* @param tx_cb Callback to be called before transport manager is sending
* outgoing message.
* @param p_mgr Pointer to receive the new transport manager.
*
* @return PJ_SUCCESS or the appropriate error code on error.
*/
PJ_DECL(pj_status_t) pjsip_tpmgr_create( pj_pool_t *pool,
pjsip_endpoint * endpt,
pjsip_rx_callback rx_cb,
pjsip_tx_callback tx_cb,
pjsip_tpmgr **p_mgr);
/**
* Find out the appropriate local address info (IP address and port) to
* advertise in Contact header based on the remote address to be
* contacted. The local address info would be the address name of the
* transport or listener which will be used to send the request.
*
* In this implementation, it will only select the transport based on
* the transport type in the request.
*
* @see pjsip_tpmgr_find_local_addr2()
*
* @param tpmgr The transport manager.
* @param pool Pool to allocate memory for the IP address.
* @param type Destination address to contact.
* @param sel Optional pointer to prefered transport, if any.
* @param ip_addr Pointer to receive the IP address.
* @param port Pointer to receive the port number.
*
* @return PJ_SUCCESS, or the appropriate error code.
*/
PJ_DECL(pj_status_t) pjsip_tpmgr_find_local_addr( pjsip_tpmgr *tpmgr,
pj_pool_t *pool,
pjsip_transport_type_e type,
const pjsip_tpselector *sel,
pj_str_t *ip_addr,
int *port);
/**
* Parameter for pjsip_tpmgr_find_local_addr2() function.
*/
typedef struct pjsip_tpmgr_fla2_param
{
/**
* Specify transport type to use. This must be set.
*/
pjsip_transport_type_e tp_type;
/**
* Optional pointer to preferred transport, if any.
*/
const pjsip_tpselector *tp_sel;
/**
* Destination host, if known. The destination host is needed
* if \a local_if field below is set.
*/
pj_str_t dst_host;
/**
* Specify if the function should return which local interface
* to use for the specified destination in \a dst_host. By definition,
* the returned address will always be local interface address.
*/
pj_bool_t local_if;
/**
* The returned address.
*/
pj_str_t ret_addr;
/**
* The returned port.
*/
pj_uint16_t ret_port;
/**
* Returned pointer to the transport. Only set if local_if is set.
*/
const void *ret_tp;
} pjsip_tpmgr_fla2_param;
/**
* Initialize with default values.
*
* @param prm The parameter to be initialized.
*/
PJ_DECL(void) pjsip_tpmgr_fla2_param_default(pjsip_tpmgr_fla2_param *prm);
/**
* Find out the appropriate local address info (IP address and port) to
* advertise in Contact or Via header header based on the remote address
* to be contacted. The local address info would be the address name of the
* transport or listener which will be used to send the request.
*
* @see pjsip_tpmgr_find_local_addr()
*
* @param tpmgr The transport manager.
* @param pool Pool to allocate memory for the IP address.
* @param param Function input and output parameters.
*
* @return PJ_SUCCESS, or the appropriate error code.
*/
PJ_DECL(pj_status_t) pjsip_tpmgr_find_local_addr2(pjsip_tpmgr *tpmgr,
pj_pool_t *pool,
pjsip_tpmgr_fla2_param *prm);
/**
* Return number of transports currently registered to the transport
* manager.
*
* @param mgr The transport manager.
*
* @return Number of transports.
*/
PJ_DECL(unsigned) pjsip_tpmgr_get_transport_count(pjsip_tpmgr *mgr);
/**
* Destroy a transport manager. Normally application doesn't need to call
* this function directly, since a transport manager will be created and
* destroyed automatically by the SIP endpoint.
*
* @param mgr The transport manager.
*
* @return PJ_SUCCESS on success.
*/
PJ_DECL(pj_status_t) pjsip_tpmgr_destroy(pjsip_tpmgr *mgr);
/**
* Dump transport info and status to log.
*
* @param mgr The transport manager.
*/
PJ_DECL(void) pjsip_tpmgr_dump_transports(pjsip_tpmgr *mgr);
/*****************************************************************************
*
* PUBLIC API
*
*****************************************************************************/
/**
* Find transport to be used to send message to remote destination. If no
* suitable transport is found, a new one will be created.
*
* This is an internal function since normally application doesn't have access
* to transport manager. Application should use pjsip_endpt_acquire_transport()
* instead.
*
* @param mgr The transport manager instance.
* @param type The type of transport to be acquired.
* @param remote The remote address to send message to.
* @param addr_len Length of the remote address.
* @param sel Optional pointer to transport selector instance which is
* used to find explicit transport, if required.
* @param tp Pointer to receive the transport instance, if one is found.
*
* @return PJ_SUCCESS on success, or the appropriate error code.
*/
PJ_DECL(pj_status_t) pjsip_tpmgr_acquire_transport(pjsip_tpmgr *mgr,
pjsip_transport_type_e type,
const pj_sockaddr_t *remote,
int addr_len,
const pjsip_tpselector *sel,
pjsip_transport **tp);
/**
* Find suitable transport for sending SIP message to specified remote
* destination by also considering the outgoing SIP message. If no suitable
* transport is found, a new one will be created.
*
* This is an internal function since normally application doesn't have access
* to transport manager. Application should use pjsip_endpt_acquire_transport2()
* instead.
*
* @param mgr The transport manager instance.
* @param type The type of transport to be acquired.
* @param remote The remote address to send message to.
* @param addr_len Length of the remote address.
* @param sel Optional pointer to transport selector instance which is
* used to find explicit transport, if required.
* @param tdata Optional pointer to data to be sent.
* @param tp Pointer to receive the transport instance, if one is found.
*
* @return PJ_SUCCESS on success, or the appropriate error code.
*/
PJ_DECL(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr,
pjsip_transport_type_e type,
const pj_sockaddr_t *remote,
int addr_len,
const pjsip_tpselector *sel,
pjsip_tx_data *tdata,
pjsip_transport **tp);
/**
* Type of callback to receive notification when message or raw data
* has been sent.
*
* @param token The token that was given when calling the function
* to send message or raw data.
* @param tdata The transmit buffer used to send the message.
* @param bytes_sent Number of bytes sent. On success, the value will be
* positive number indicating the number of bytes sent.
* On failure, the value will be a negative number of
* the error code (i.e. bytes_sent = -status).
*/
typedef void (*pjsip_tp_send_callback)(void *token, pjsip_tx_data *tdata,
pj_ssize_t bytes_sent);
/**
* This is a low-level function to send a SIP message using the specified
* transport to the specified destination.
*
* @param tr The SIP transport to be used.
* @param tdata Transmit data buffer containing SIP message.
* @param addr Destination address.
* @param addr_len Length of destination address.
* @param token Arbitrary token to be returned back to callback.
* @param cb Optional callback to be called to notify caller about
* the completion status of the pending send operation.
*
* @return If the message has been sent successfully, this function
* will return PJ_SUCCESS and the callback will not be
* called. If message cannot be sent immediately, this
* function will return PJ_EPENDING, and application will
* be notified later about the completion via the callback.
* Any statuses other than PJ_SUCCESS or PJ_EPENDING
* indicates immediate failure, and in this case the
* callback will not be called.
*/
PJ_DECL(pj_status_t) pjsip_transport_send( pjsip_transport *tr,
pjsip_tx_data *tdata,
const pj_sockaddr_t *addr,
int addr_len,
void *token,
pjsip_tp_send_callback cb);
/**
* This is a low-level function to send raw data to a destination.
*
* See also #pjsip_endpt_send_raw() and #pjsip_endpt_send_raw_to_uri().
*
* @param mgr Transport manager.
* @param tp_type Transport type.
* @param sel Optional pointer to transport selector instance if
* application wants to use a specific transport instance
* rather then letting transport manager finds the suitable
* transport.
* @param tdata Optional transmit data buffer to be used. If this value
* is NULL, this function will create one internally. If
* tdata is specified, this function will decrement the
* reference counter upon completion.
* @param raw_data The data to be sent.
* @param data_len The length of the data.
* @param addr Destination address.
* @param addr_len Length of destination address.
* @param token Arbitrary token to be returned back to callback.
* @param cb Optional callback to be called to notify caller about
* the completion status of the pending send operation.
*
* @return If the message has been sent successfully, this function
* will return PJ_SUCCESS and the callback will not be
* called. If message cannot be sent immediately, this
* function will return PJ_EPENDING, and application will
* be notified later about the completion via the callback.
* Any statuses other than PJ_SUCCESS or PJ_EPENDING
* indicates immediate failure, and in this case the
* callback will not be called.
*/
PJ_DECL(pj_status_t) pjsip_tpmgr_send_raw(pjsip_tpmgr *mgr,
pjsip_transport_type_e tp_type,
const pjsip_tpselector *sel,
pjsip_tx_data *tdata,
const void *raw_data,
pj_size_t data_len,
const pj_sockaddr_t *addr,
int addr_len,
void *token,
pjsip_tp_send_callback cb);
/**
* Enumeration of transport state types.
*/
typedef enum pjsip_transport_state
{
PJSIP_TP_STATE_CONNECTED, /**< Transport connected, applicable only
to connection-oriented transports
such as TCP and TLS. */
PJSIP_TP_STATE_DISCONNECTED /**< Transport disconnected, applicable
only to connection-oriented
transports such as TCP and TLS. */
} pjsip_transport_state;
/**
* Definition of transport state listener key.
*/
typedef void pjsip_tp_state_listener_key;
/**
* Structure of transport state info passed by #pjsip_tp_state_callback.
*/
typedef struct pjsip_transport_state_info {
/**
* The last error code related to the transport state.
*/
pj_status_t status;
/**
* Optional extended info, the content is specific for each transport type.
*/
void *ext_info;
/**
* Optional user data. In global transport state notification, this will
* always be NULL.
*/
void *user_data;
} pjsip_transport_state_info;
/**
* Type of callback to receive transport state notifications, such as
* transport connected/disconnected. Application may shutdown the transport
* in this callback.
*
* @param tp The transport instance.
* @param state The transport state.
* @param info The transport state info.
*/
typedef void (*pjsip_tp_state_callback)(
pjsip_transport *tp,
pjsip_transport_state state,
const pjsip_transport_state_info *info);
/**
* Set callback of global transport state notification. The caller will be
* notified whenever the state of any transport is changed. The type of events
* are defined in #pjsip_transport_state.
*
* Note that this function will override the existing callback, if any, so
* application is recommended to keep the old callback and manually forward
* the notification to the old callback, otherwise other component that
* concerns about the transport state will no longer receive transport state
* events.
*
* @param mgr Transport manager.
* @param cb Callback to be called to notify caller about transport
* state changing.
*
* @return PJ_SUCCESS on success, or the appropriate error code.
*/
PJ_DECL(pj_status_t) pjsip_tpmgr_set_state_cb(pjsip_tpmgr *mgr,
pjsip_tp_state_callback cb);
/**
* Get the callback of global transport state notification.
*
* @param mgr Transport manager.
*
* @return The transport state callback or NULL if it is not set.
*/
PJ_DECL(pjsip_tp_state_callback) pjsip_tpmgr_get_state_cb(
const pjsip_tpmgr *mgr);
/**
* Add a listener to the specified transport for transport state notification.
*
* @param tp The transport.
* @param cb Callback to be called to notify listener about transport
* state changing.
* @param user_data The user data.
* @param key Output key, used to remove this listener.
*
* @return PJ_SUCCESS on success, or the appropriate error code.
*/
PJ_DECL(pj_status_t) pjsip_transport_add_state_listener (
pjsip_transport *tp,
pjsip_tp_state_callback cb,
void *user_data,
pjsip_tp_state_listener_key **key);
/**
* Remove a listener from the specified transport for transport state
* notification.
*
* @param tp The transport.
* @param key The listener key.
* @param user_data The user data, for validation purpose.
*
* @return PJ_SUCCESS on success, or the appropriate error code.
*/
PJ_DECL(pj_status_t) pjsip_transport_remove_state_listener (
pjsip_transport *tp,
pjsip_tp_state_listener_key *key,
const void *user_data);
/**
* @}
*/
PJ_END_DECL
#endif /* __PJSIP_SIP_TRANSPORT_H__ */