123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557 |
- /*
- * 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_TRANSACTION_H__
- #define __PJSIP_SIP_TRANSACTION_H__
- /**
- * @file sip_transaction.h
- * @brief SIP Transaction
- */
- #include <pjsip/sip_msg.h>
- #include <pjsip/sip_util.h>
- #include <pjsip/sip_transport.h>
- #include <pj/timer.h>
- PJ_BEGIN_DECL
- /**
- * @defgroup PJSIP_TRANSACT Transaction Layer
- * @brief Provides statefull message processing.
- *
- * This module provides stateful processing to incoming or outgoing SIP
- * messages.
- * Before performing any stateful operations, application must register the
- * transaction layer module by calling #pjsip_tsx_layer_init_module().
- *
- * Application should link with <b>pjsip-core</b> library to
- * use the transaction layer.
- */
- /**
- * @defgroup PJSIP_TRANSACT_TRANSACTION Transaction
- * @ingroup PJSIP_TRANSACT
- * @brief Transaction instance for all types of SIP transactions.
- * @{
- * The pjsip_transaction describes SIP transaction, and is used for
- * both INVITE and non-INVITE, UAC or UAS. Application must register the
- * transaction layer module with #pjsip_tsx_layer_init_module() before
- * performing any stateful operations.
- */
- /**
- * This enumeration represents transaction state.
- */
- typedef enum pjsip_tsx_state_e
- {
- PJSIP_TSX_STATE_NULL, /**< For UAC, before any message is sent. */
- PJSIP_TSX_STATE_CALLING, /**< For UAC, just after request is sent. */
- PJSIP_TSX_STATE_TRYING, /**< For UAS, just after request is received.*/
- PJSIP_TSX_STATE_PROCEEDING, /**< For UAS/UAC, after provisional response.*/
- PJSIP_TSX_STATE_COMPLETED, /**< For UAS/UAC, after final response. */
- PJSIP_TSX_STATE_CONFIRMED, /**< For UAS, after ACK is received. */
- PJSIP_TSX_STATE_TERMINATED, /**< For UAS/UAC, before it's destroyed. */
- PJSIP_TSX_STATE_DESTROYED, /**< For UAS/UAC, will be destroyed now. */
- PJSIP_TSX_STATE_MAX /**< Number of states. */
- } pjsip_tsx_state_e;
- /**
- * This structure describes SIP transaction object. The transaction object
- * is used to handle both UAS and UAC transaction.
- */
- struct pjsip_transaction
- {
- /*
- * Administrivia
- */
- pj_pool_t *pool; /**< Pool owned by the tsx. */
- pjsip_module *tsx_user; /**< Transaction user. */
- pjsip_endpoint *endpt; /**< Endpoint instance. */
- pj_bool_t terminating; /**< terminate() was called */
- pj_grp_lock_t *grp_lock; /**< Transaction grp lock. */
- pj_mutex_t *mutex_b; /**< Second mutex to avoid
- deadlock. It is used to
- protect timer. */
- /*
- * Transaction identification.
- */
- char obj_name[PJ_MAX_OBJ_NAME]; /**< Log info. */
- pjsip_role_e role; /**< Role (UAS or UAC) */
- pjsip_method method; /**< The method. */
- pj_int32_t cseq; /**< The CSeq */
- pj_str_t transaction_key;/**< Hash table key. */
- pj_str_t transaction_key2;/**< Hash table key (2)
- for merged requests
- tsx lookup. */
- pj_uint32_t hashed_key; /**< Key's hashed value. */
- pj_uint32_t hashed_key2; /**< Key's hashed value (2).*/
- pj_str_t branch; /**< The branch Id. */
- /*
- * State and status.
- */
- int status_code; /**< Last status code seen. */
- pj_str_t status_text; /**< Last reason phrase. */
- pjsip_tsx_state_e state; /**< State. */
- int handle_200resp; /**< UAS 200/INVITE retrsm.*/
- int tracing; /**< Tracing enabled? */
- /** Handler according to current state. */
- pj_status_t (*state_handler)(struct pjsip_transaction *, pjsip_event *);
- /*
- * Transport.
- */
- pjsip_transport *transport; /**< Transport to use. */
- pj_bool_t is_reliable; /**< Transport is reliable. */
- pj_sockaddr addr; /**< Destination address. */
- int addr_len; /**< Address length. */
- pjsip_response_addr res_addr; /**< Response address. */
- unsigned transport_flag; /**< Miscelaneous flag. */
- pj_status_t transport_err; /**< Internal error code. */
- pjsip_tpselector tp_sel; /**< Transport selector. */
- pjsip_tx_data *pending_tx; /**< Tdata which caused
- pending transport flag
- to be set on tsx. */
- pjsip_tp_state_listener_key *tp_st_key; /**< Transport state listener
- key. */
- /*
- * Messages and timer.
- */
- pjsip_tx_data *last_tx; /**< Msg kept for retrans. */
- int retransmit_count;/**< Retransmission count. */
- pj_timer_entry retransmit_timer;/**< Retransmit timer. */
- pj_timer_entry timeout_timer; /**< Timeout timer. */
- /** Module specific data. */
- void *mod_data[PJSIP_MAX_MODULE];
- };
- /**
- * Create and register transaction layer module to the specified endpoint.
- *
- * @param endpt The endpoint instance.
- *
- * @return PJ_SUCCESS on success.
- */
- PJ_DECL(pj_status_t) pjsip_tsx_layer_init_module(pjsip_endpoint *endpt);
- /**
- * Get the instance of the transaction layer module.
- *
- * @return The transaction layer module.
- */
- PJ_DECL(pjsip_module*) pjsip_tsx_layer_instance(void);
- /**
- * Unregister and destroy transaction layer module.
- *
- * @return PJ_SUCCESS on success.
- */
- PJ_DECL(pj_status_t) pjsip_tsx_layer_destroy(void);
- /**
- * Retrieve the current number of transactions currently registered
- * in the hash table.
- *
- * @return Number of transactions.
- */
- PJ_DECL(unsigned) pjsip_tsx_layer_get_tsx_count(void);
- /**
- * Find a transaction with the specified key. The transaction key normally
- * is created by calling #pjsip_tsx_create_key() from an incoming message.
- *
- * IMPORTANT: To prevent deadlock, application should use
- * #pjsip_tsx_layer_find_tsx2() instead which only adds a reference to
- * the transaction instead of locking it.
- *
- * @param key The key string to find the transaction.
- * @param lock If non-zero, transaction will be locked before the
- * function returns, to make sure that it's not deleted
- * by other threads.
- *
- * @return The matching transaction instance, or NULL if transaction
- * can not be found.
- */
- PJ_DECL(pjsip_transaction*) pjsip_tsx_layer_find_tsx( const pj_str_t *key,
- pj_bool_t lock );
- /**
- * Find a transaction with the specified key. The transaction key normally
- * is created by calling #pjsip_tsx_create_key() from an incoming message.
- *
- * @param key The key string to find the transaction.
- * @param add_ref If non-zero, transaction's reference will be added
- * by one before the function returns, to make sure that
- * it's not deleted by other threads.
- *
- * @return The matching transaction instance, or NULL if transaction
- * can not be found.
- */
- PJ_DECL(pjsip_transaction*) pjsip_tsx_layer_find_tsx2( const pj_str_t *key,
- pj_bool_t add_ref );
- /**
- * Create, initialize, and register a new transaction as UAC from the
- * specified transmit data (\c tdata). The transmit data must have a valid
- * \c Request-Line and \c CSeq header.
- *
- * If \c Via header does not exist, it will be created along with a unique
- * \c branch parameter. If it exists and contains branch parameter, then
- * the \c branch parameter will be used as is as the transaction key. If
- * it exists but branch parameter doesn't exist, a unique branch parameter
- * will be created.
- *
- * @param tsx_user Module to be registered as transaction user of the new
- * transaction, which will receive notification from the
- * transaction via on_tsx_state() callback.
- * @param tdata The outgoing request message.
- * @param p_tsx On return will contain the new transaction instance.
- *
- * @return PJ_SUCCESS if successfull.
- */
- PJ_DECL(pj_status_t) pjsip_tsx_create_uac( pjsip_module *tsx_user,
- pjsip_tx_data *tdata,
- pjsip_transaction **p_tsx);
- /**
- * Variant of pjsip_tsx_create_uac() with additional parameter to specify
- * the group lock to use. Group lock can be used to synchronize locking
- * among several objects to prevent deadlock, and to synchronize the
- * lifetime of objects sharing the same group lock.
- *
- * See pjsip_tsx_create_uac() for general info about this function.
- *
- * @param tsx_user Module to be registered as transaction user of the new
- * transaction, which will receive notification from the
- * transaction via on_tsx_state() callback.
- * @param tdata The outgoing request message.
- * @param grp_lock Optional group lock to use by this transaction. If
- * the value is NULL, the transaction will create its
- * own group lock.
- * @param p_tsx On return will contain the new transaction instance.
- *
- * @return PJ_SUCCESS if successfull.
- */
- PJ_DECL(pj_status_t) pjsip_tsx_create_uac2(pjsip_module *tsx_user,
- pjsip_tx_data *tdata,
- pj_grp_lock_t *grp_lock,
- pjsip_transaction **p_tsx);
- /**
- * Create, initialize, and register a new transaction as UAS from the
- * specified incoming request in \c rdata. After calling this function,
- * application MUST call #pjsip_tsx_recv_msg() so that transaction
- * moves from state NULL.
- *
- * @param tsx_user Module to be registered as transaction user of the new
- * transaction, which will receive notification from the
- * transaction via on_tsx_state() callback.
- * @param rdata The received incoming request.
- * @param p_tsx On return will contain the new transaction instance.
- *
- * @return PJ_SUCCESS if successfull.
- */
- PJ_DECL(pj_status_t) pjsip_tsx_create_uas( pjsip_module *tsx_user,
- pjsip_rx_data *rdata,
- pjsip_transaction **p_tsx );
- /**
- * Variant of pjsip_tsx_create_uas() with additional parameter to specify
- * the group lock to use. Group lock can be used to synchronize locking
- * among several objects to prevent deadlock, and to synchronize the
- * lifetime of objects sharing the same group lock.
- *
- * See pjsip_tsx_create_uas() for general info about this function.
- *
- * @param tsx_user Module to be registered as transaction user of the new
- * transaction, which will receive notification from the
- * transaction via on_tsx_state() callback.
- * @param rdata The received incoming request.
- * @param grp_lock Optional group lock to use by this transaction. If
- * the value is NULL, the transaction will create its
- * own group lock.
- * @param p_tsx On return will contain the new transaction instance.
- *
- * @return PJ_SUCCESS if successfull.
- */
- PJ_DECL(pj_status_t) pjsip_tsx_create_uas2(pjsip_module *tsx_user,
- pjsip_rx_data *rdata,
- pj_grp_lock_t *grp_lock,
- pjsip_transaction **p_tsx );
- /**
- * Detect merged requests according to RFC 3261 section 8.2.2.2:
- * If the request has no tag in the To header field, the function will
- * check the request against ongoing transactions. If the From tag,
- * Call-ID, and CSeq exactly match those associated with an ongoing
- * transaction, but the request does not match that transaction based
- * on the matching rules described in section 17.2.3, the function
- * will return that transaction.
- *
- * @param rdata The received incoming request.
- *
- * @return The matching transaction, if any, or NULL.
- */
- PJ_DECL(pjsip_transaction *)
- pjsip_tsx_detect_merged_requests(pjsip_rx_data *rdata);
- /**
- * Lock/bind transaction to a specific transport/listener. This is optional,
- * as normally transport will be selected automatically based on the
- * destination of the message upon resolver completion.
- *
- * @param tsx The transaction.
- * @param sel Transport selector containing the specification of
- * transport or listener to be used by this transaction
- * to send requests.
- *
- * @return PJ_SUCCESS on success, or the appropriate error code.
- */
- PJ_DECL(pj_status_t) pjsip_tsx_set_transport(pjsip_transaction *tsx,
- const pjsip_tpselector *sel);
- /**
- * Call this function to manually feed a message to the transaction.
- * For UAS transaction, application MUST call this function after
- * UAS transaction has been created.
- *
- * This function SHOULD only be called to pass initial request message
- * to UAS transaction. Before this function returns, on_tsx_state()
- * callback of the transaction user will be called. If response message
- * is passed to this function, then on_rx_response() will also be called
- * before on_tsx_state().
- *
- * @param tsx The transaction.
- * @param rdata The message.
- */
- PJ_DECL(void) pjsip_tsx_recv_msg( pjsip_transaction *tsx,
- pjsip_rx_data *rdata);
- /**
- * Transmit message in tdata with this transaction. It is possible to
- * pass NULL in tdata for UAC transaction, which in this case the last
- * message transmitted, or the request message which was specified when
- * calling #pjsip_tsx_create_uac(), will be sent.
- *
- * This function decrements the reference counter of the transmit buffer
- * only when it returns PJ_SUCCESS;
- *
- * @param tsx The transaction.
- * @param tdata The outgoing message. If NULL is specified, then the
- * last message transmitted (or the message specified
- * in UAC initialization) will be sent.
- *
- * @return PJ_SUCCESS if successfull.
- */
- PJ_DECL(pj_status_t) pjsip_tsx_send_msg( pjsip_transaction *tsx,
- pjsip_tx_data *tdata);
- /**
- * Manually retransmit the last message transmitted by this transaction,
- * without updating the transaction state. This function is useful when
- * TU wants to maintain the retransmision by itself (for example,
- * retransmitting reliable provisional response).
- *
- * @param tsx The transaction.
- * @param tdata The outgoing message. If NULL is specified, then the
- * last message transmitted (or the message specified
- * in UAC initialization) will be sent.
- *
- *
- * @return PJ_SUCCESS if successful.
- */
- PJ_DECL(pj_status_t) pjsip_tsx_retransmit_no_state(pjsip_transaction *tsx,
- pjsip_tx_data *tdata);
- /**
- * Create transaction key, which is used to match incoming requests
- * or response (retransmissions) against transactions.
- *
- * @param pool The pool
- * @param key Output key.
- * @param role The role of the transaction.
- * @param method The method to be put as a key.
- * @param rdata The received data to calculate.
- *
- * @return PJ_SUCCESS or the appropriate error code.
- */
- PJ_DECL(pj_status_t) pjsip_tsx_create_key( pj_pool_t *pool,
- pj_str_t *key,
- pjsip_role_e role,
- const pjsip_method *method,
- const pjsip_rx_data *rdata );
- /**
- * Force terminate transaction.
- *
- * @param tsx The transaction.
- * @param code The status code to report.
- *
- * @return PJ_SUCCESS or the appropriate error code.
- */
- PJ_DECL(pj_status_t) pjsip_tsx_terminate( pjsip_transaction *tsx,
- int code );
- /**
- * Force terminate transaction asynchronously, using the transaction
- * internal timer.
- *
- * @param tsx The transaction.
- * @param code The status code to report.
- *
- * @return PJ_SUCCESS or the appropriate error code.
- */
- PJ_DECL(pj_status_t) pjsip_tsx_terminate_async(pjsip_transaction *tsx,
- int code );
- /**
- * Cease retransmission on the UAC transaction. The UAC transaction is
- * still considered running, and it will complete when either final
- * response is received or the transaction times out.
- *
- * This operation normally is used for INVITE transaction only, when
- * the transaction is cancelled before any provisional response has been
- * received.
- *
- * @param tsx The transaction.
- *
- * @return PJ_SUCCESS or the appropriate error code.
- */
- PJ_DECL(pj_status_t) pjsip_tsx_stop_retransmit(pjsip_transaction *tsx);
- /**
- * Start a timer to terminate transaction after the specified time
- * has elapsed. This function is only valid for INVITE transaction,
- * and only before final response is received for the INVITE transaction.
- * It is normally called after the UAC has sent CANCEL for this
- * INVITE transaction.
- *
- * The purpose of this function is to terminate the transaction if UAS
- * does not send final response to this INVITE transaction even after
- * it sends 200/OK to CANCEL (for example when the UAS complies to RFC
- * 2543).
- *
- * Once this timer is set, the transaction will be terminated either when
- * a final response is received or the timer expires.
- *
- * @param tsx The transaction.
- * @param millisec Timeout value in milliseconds.
- *
- * @return PJ_SUCCESS or the appropriate error code.
- */
- PJ_DECL(pj_status_t) pjsip_tsx_set_timeout(pjsip_transaction *tsx,
- unsigned millisec);
- /**
- * Change timer values used by transaction layer. Currently scheduled
- * timers will not be changed. Any value set to 0 will be left
- * unchanged.
- *
- * @param t1 Transaction T1 timeout, in msec
- * @param t2 Transaction T2 timeout, in msec
- * @param t4 Transaction completed timer for non-INVITE, in msec
- * @param td Transaction completed timer for INVITE, in msec
- */
- PJ_DECL(void) pjsip_tsx_set_timers(unsigned t1, unsigned t2, unsigned t4,
- unsigned td);
- /**
- * (Re)Initializes timer values from pjsip_cfg().
- */
- PJ_DECL(void) pjsip_tsx_initialize_timer_values(void);
- /**
- * Set maximum retransmission count in transaction layer for outgoing
- * requests. When retransmission counter reaches the specified number,
- * the transaction will be considered timeout. This will affect any
- * ongoing transactions immediately.
- *
- * By default (or when this is set to -1), retransmission number will
- * not cause a transaction to be timeout, only the timer settings will
- * cause transaction timeout. Also, this will not override the timer
- * settings, i.e: if the timeout timer occurs before the maximum
- * retransmission is reached, the transaction will still gets timeout.
- *
- * When this is set to zero or possitive number P, a transaction timeout
- * will occur right before the retransmission number (P+1). For example,
- * if this is set to 1 there will be two transmissions: the initial
- * transmission and one retransmission, before the transaction gets timeout.
- *
- * @param max Maximum retransmission count.
- */
- PJ_DECL(void) pjsip_tsx_set_max_retransmit_count(int max);
- /**
- * Get the transaction instance in the incoming message. If the message
- * has a corresponding transaction, this function will return non NULL
- * value.
- *
- * @param rdata The incoming message buffer.
- *
- * @return The transaction instance associated with this message,
- * or NULL if the message doesn't match any transactions.
- */
- PJ_DECL(pjsip_transaction*) pjsip_rdata_get_tsx( pjsip_rx_data *rdata );
- /**
- * @}
- */
- /*
- * Internal.
- */
- /**
- * Dump transaction layer.
- */
- PJ_DECL(void) pjsip_tsx_layer_dump(pj_bool_t detail);
- /**
- * Get the string name for the state.
- * @param state State
- */
- PJ_DECL(const char *) pjsip_tsx_state_str(pjsip_tsx_state_e state);
- /**
- * Get the role name.
- * @param role Role.
- */
- PJ_DECL(const char *) pjsip_role_name(pjsip_role_e role);
- PJ_END_DECL
- #endif /* __PJSIP_TRANSACT_H__ */
|