From 944562492d0c16b9e44ec4e1cc97657846d82cd0 Mon Sep 17 00:00:00 2001 From: Benny Prijono Date: Fri, 30 Dec 2005 23:50:15 +0000 Subject: Basic module, transport, and sending messages git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@106 74dad513-b988-da41-8d7b-12977e46ad98 --- pjsip/include/pjsip/sip_endpoint.h | 94 ++++++++---- pjsip/include/pjsip/sip_errno.h | 42 +++++- pjsip/include/pjsip/sip_module.h | 88 +++++++---- pjsip/include/pjsip/sip_msg.h | 50 +++---- pjsip/include/pjsip/sip_transport.h | 22 ++- pjsip/include/pjsip/sip_transport_udp.h | 2 +- pjsip/include/pjsip/sip_util.h | 257 ++++++++++++++++++++++++++------ pjsip/include/pjsip_core.h | 1 + 8 files changed, 413 insertions(+), 143 deletions(-) (limited to 'pjsip/include') diff --git a/pjsip/include/pjsip/sip_endpoint.h b/pjsip/include/pjsip/sip_endpoint.h index 8254d508..d9d03a97 100644 --- a/pjsip/include/pjsip/sip_endpoint.h +++ b/pjsip/include/pjsip/sip_endpoint.h @@ -115,6 +115,34 @@ PJ_DECL(const pj_str_t*) pjsip_endpt_name(const pjsip_endpoint *endpt); PJ_DECL(void) pjsip_endpt_handle_events( pjsip_endpoint *endpt, const pj_time_val *max_timeout); + +/** + * Schedule timer to endpoint's timer heap. Application must poll the endpoint + * periodically (by calling #pjsip_endpt_handle_events) to ensure that the + * timer events are handled in timely manner. When the timeout for the timer + * has elapsed, the callback specified in the entry argument will be called. + * This function, like all other endpoint functions, is thread safe. + * + * @param endpt The endpoint. + * @param entry The timer entry. + * @param delay The relative delay of the timer. + * @return PJ_OK (zero) if successfull. + */ +PJ_DECL(pj_status_t) pjsip_endpt_schedule_timer( pjsip_endpoint *endpt, + pj_timer_entry *entry, + const pj_time_val *delay ); + +/** + * Cancel the previously registered timer. + * This function, like all other endpoint functions, is thread safe. + * + * @param endpt The endpoint. + * @param entry The timer entry previously registered. + */ +PJ_DECL(void) pjsip_endpt_cancel_timer( pjsip_endpoint *endpt, + pj_timer_entry *entry ); + + /** * Dump endpoint status to the log. This will print the status to the log * with log level 3. @@ -126,6 +154,35 @@ PJ_DECL(void) pjsip_endpt_handle_events( pjsip_endpoint *endpt, */ PJ_DECL(void) pjsip_endpt_dump( pjsip_endpoint *endpt, pj_bool_t detail ); + +/** + * Register new module to the endpoint. + * The endpoint will then call the load and start function in the module to + * properly initialize the module, and assign a unique module ID for the + * module. + * + * @param endpt The endpoint. + * @param module The module to be registered. + * + * @return PJ_SUCCESS on success. + */ +PJ_DECL(pj_status_t) pjsip_endpt_register_module( pjsip_endpoint *endpt, + pjsip_module *module ); + +/** + * Unregister a module from the endpoint. + * The endpoint will then call the stop and unload function in the module to + * properly shutdown the module. + * + * @param endpt The endpoint. + * @param module The module to be registered. + * + * @return PJ_SUCCESS on success. + */ +PJ_DECL(pj_status_t) pjsip_endpt_unregister_module( pjsip_endpoint *endpt, + pjsip_module *module ); + + /** * Create pool from the endpoint. All SIP components should allocate their * memory pool by calling this function, to make sure that the pools are @@ -155,32 +212,6 @@ PJ_DECL(pj_pool_t*) pjsip_endpt_create_pool( pjsip_endpoint *endpt, PJ_DECL(void) pjsip_endpt_destroy_pool( pjsip_endpoint *endpt, pj_pool_t *pool ); -/** - * Schedule timer to endpoint's timer heap. Application must poll the endpoint - * periodically (by calling #pjsip_endpt_handle_events) to ensure that the - * timer events are handled in timely manner. When the timeout for the timer - * has elapsed, the callback specified in the entry argument will be called. - * This function, like all other endpoint functions, is thread safe. - * - * @param endpt The endpoint. - * @param entry The timer entry. - * @param delay The relative delay of the timer. - * @return PJ_OK (zero) if successfull. - */ -PJ_DECL(pj_status_t) pjsip_endpt_schedule_timer( pjsip_endpoint *endpt, - pj_timer_entry *entry, - const pj_time_val *delay ); - -/** - * Cancel the previously registered timer. - * This function, like all other endpoint functions, is thread safe. - * - * @param endpt The endpoint. - * @param entry The timer entry previously registered. - */ -PJ_DECL(void) pjsip_endpt_cancel_timer( pjsip_endpoint *endpt, - pj_timer_entry *entry ); - /** * Create a new transaction. After creating the transaction, application MUST * initialize the transaction as either UAC or UAS (by calling @@ -278,11 +309,12 @@ PJ_DECL(pj_ioqueue_t*) pjsip_endpt_get_ioqueue(pjsip_endpoint *endpt); * * @see pjsip_transport_get */ -PJ_DECL(pj_status_t) pjsip_endpt_alloc_transport( pjsip_endpoint *endpt, - pjsip_transport_type_e type, - const pj_sockaddr *remote, - int addr_len, - pjsip_transport **p_transport); +PJ_DECL(pj_status_t) +pjsip_endpt_acquire_transport( pjsip_endpoint *endpt, + pjsip_transport_type_e type, + const pj_sockaddr_t *remote, + int addr_len, + pjsip_transport **p_transport); /** * Get additional headers to be put in outgoing request message. diff --git a/pjsip/include/pjsip/sip_errno.h b/pjsip/include/pjsip/sip_errno.h index eefda673..4d50c75d 100644 --- a/pjsip/include/pjsip/sip_errno.h +++ b/pjsip/include/pjsip/sip_errno.h @@ -93,7 +93,7 @@ PJ_DECL(pj_str_t) pjsip_strerror( pj_status_t status, char *buffer, ***********************************************************/ /** * @hideinitializer - * Invalid message (syntax error) + * General invalid message error (e.g. syntax error) */ #define PJSIP_EINVALIDMSG (PJSIP_ERRNO_START_PJSIP + 20) /* 171020 */ /** @@ -111,21 +111,47 @@ PJ_DECL(pj_str_t) pjsip_strerror( pj_status_t status, char *buffer, * Message not completely received. */ #define PJSIP_EPARTIALMSG (PJSIP_ERRNO_START_PJSIP + 23) /* 171023 */ +/** + * @hideinitializer + * Missing Request-URI. + */ +#define PJSIP_EMISSINGREQURI (PJSIP_ERRNO_START_PJSIP + 24) /* 171024 */ /** * @hideinitializer * Missing required header(s). */ -#define PJSIP_EMISSINGHDR (PJSIP_ERRNO_START_PJSIP + 24) /* 171024 */ +#define PJSIP_EMISSINGHDR (PJSIP_ERRNO_START_PJSIP + 25) /* 171025 */ +/** + * @hideinitializer + * Missing message body. + */ +#define PJSIP_EMISSINGBODY (PJSIP_ERRNO_START_PJSIP + 26) /* 171026 */ /** * @hideinitializer * Invalid Via header in response (sent-by, etc). */ -#define PJSIP_EINVALIDVIA (PJSIP_ERRNO_START_PJSIP + 25) /* 171025 */ +#define PJSIP_EINVALIDVIA (PJSIP_ERRNO_START_PJSIP + 27) /* 171027 */ /** * @hideinitializer * Multiple Via headers in response. */ -#define PJSIP_EMULTIPLEVIA (PJSIP_ERRNO_START_PJSIP + 26) /* 171026 */ +#define PJSIP_EMULTIPLEVIA (PJSIP_ERRNO_START_PJSIP + 28) /* 171028 */ +/** + * @hideinitializer + * Invalid request URI. + */ +#define PJSIP_EINVALIDREQURI (PJSIP_ERRNO_START_PJSIP + 29) /* 171029 */ +/** + * @hideinitializer + * Expecting request message. + */ +#define PJSIP_ENOTREQUESTMSG (PJSIP_ERRNO_START_PJSIP + 30) /* 171030 */ +/** + * @hideinitializer + * Expecting response message. + */ +#define PJSIP_ENOTRESPONSEMSG (PJSIP_ERRNO_START_PJSIP + 31) /* 171031 */ + /************************************************************ * TRANSPORT ERRORS @@ -144,7 +170,13 @@ PJ_DECL(pj_str_t) pjsip_strerror( pj_status_t status, char *buffer, * @hideinitializer * Rx buffer overflow. See also PJSIP_EMSGTOOLONG. */ -#define PJSIP_ERXOVERFLOW (PJSIP_ERRNO_START_PJSIP + 42)/* 171042 */ +#define PJSIP_ERXOVERFLOW (PJSIP_ERRNO_START_PJSIP + 42) /* 171042 */ +/** + * @hideinitializer + * This is not really an error, it just informs application that + * transmit data has been deleted on return of pjsip_tx_data_dec_ref(). + */ +#define PJSIP_EBUFDESTROYED (PJSIP_ERRNO_START_PJSIP + 43) /* 171043 */ /************************************************************ diff --git a/pjsip/include/pjsip/sip_module.h b/pjsip/include/pjsip/sip_module.h index 345be88a..0f188194 100644 --- a/pjsip/include/pjsip/sip_module.h +++ b/pjsip/include/pjsip/sip_module.h @@ -41,28 +41,31 @@ PJ_BEGIN_DECL */ struct pjsip_module { + /** To allow chaining of modules in the endpoint. */ + PJ_DECL_LIST_MEMBER(struct pjsip_module); + /** * Module name. */ pj_str_t name; /** - * Flag to indicate the type of interfaces supported by the module. + * Module ID. */ - pj_uint32_t flag; + int id; /** * Integer number to identify module initialization and start order with * regard to other modules. Higher number will make the module gets * initialized later. */ - pj_uint32_t priority; + int priority; /** * Opaque data which can be used by a module to identify a resource within * the module itself. */ - void *mod_data; + void *user_data; /** * Number of methods supported by this module. @@ -78,22 +81,24 @@ struct pjsip_module * Pointer to function to be called to initialize the module. * * @param endpt The endpoint instance. - * @param mod The module. - * @param id The unique module ID assigned to this module. - * - * @return Module should return zero when initialization succeed. + * @return Module should return PJ_SUCCESS to indicate success. */ - pj_status_t (*init_module)(pjsip_endpoint *endpt, - struct pjsip_module *mod, pj_uint32_t id); + pj_status_t (*load)(pjsip_endpoint *endpt); /** * Pointer to function to be called to start the module. * - * @param mod The module. - * * @return Module should return zero to indicate success. */ - pj_status_t (*start_module)(struct pjsip_module *mod); + pj_status_t (*start)(void); + + /** + * Pointer to function to be called to deinitialize the module before + * it is unloaded. + * + * @return Module should return PJ_SUCCESS to indicate success. + */ + pj_status_t (*stop)(void); /** * Pointer to function to be called to deinitialize the module before @@ -101,34 +106,55 @@ struct pjsip_module * * @param mod The module. * - * @return Module should return zero to indicate success. + * @return Module should return PJ_SUCCESS to indicate success. */ - pj_status_t (*deinit_module)(struct pjsip_module *mod); + pj_status_t (*unload)(void); /** - * Pointer to function to receive transaction related events. - * If the module doesn't wish to receive such notification, this member - * must be set to NULL. + * Called to process incoming request. * - * @param mod The module. - * @param event The transaction event. + * @param rdata The incoming message. + * + * @return Module should return PJ_TRUE if it handles the request, + * or otherwise it should return PJ_FALSE to allow other + * modules to handle the request. */ - void (*tsx_handler)(struct pjsip_module *mod, pjsip_event *event); + pj_bool_t (*on_rx_request)(pjsip_rx_data *rdata); + + /** + * Called to processed incoming response. + * + * @param rdata The incoming message. + * + * @return Module should return PJ_TRUE if it handles the + * response, or otherwise it should return PJ_FALSE to + * allow other modules to handle the response. + */ + pj_bool_t (*on_rx_response)(pjsip_rx_data *rdata); + + /** + * Called when this module is acting as transaction user for the specified + * transaction, when the transaction's state has changed. + * + * @param tsx The transaction. + * @param event The event which has caused the transaction state + * to change. + */ + void (*on_tsx_state)(pjsip_transaction *tsx, pjsip_event *event); + }; /** - * Prototype of function to register static modules (eg modules that are - * linked staticly with the application). This function must be implemented - * by any applications that use PJSIP library. - * - * @param count [input/output] On input, it contains the maximum number of - * elements in the array. On output, the function fills with - * the number of modules to be registered. - * @param modules [output] array of pointer to modules to be registered. + * Module priority guidelines. */ -pj_status_t register_static_modules( pj_size_t *count, - pjsip_module **modules ); +enum pjsip_module_priority +{ + PJSIP_MOD_PRIORITY_TSX_LAYER = 4, + PJSIP_MOD_PRIORITY_UA_PROXY_LAYER = 16, + PJSIP_MOD_PRIORITY_APPLICATION = 32, +}; + /** * @} diff --git a/pjsip/include/pjsip/sip_msg.h b/pjsip/include/pjsip/sip_msg.h index 836ce37b..e1866048 100644 --- a/pjsip/include/pjsip/sip_msg.h +++ b/pjsip/include/pjsip/sip_msg.h @@ -52,27 +52,14 @@ PJ_BEGIN_DECL */ typedef enum pjsip_method_e { - /** INVITE method, for establishing dialogs. */ - PJSIP_INVITE_METHOD, + PJSIP_INVITE_METHOD, /**< INVITE method, for establishing dialogs. */ + PJSIP_CANCEL_METHOD, /**< CANCEL method, for cancelling request. */ + PJSIP_ACK_METHOD, /**< ACK method. */ + PJSIP_BYE_METHOD, /**< BYE method, for terminating dialog. */ + PJSIP_REGISTER_METHOD, /**< REGISTER method. */ + PJSIP_OPTIONS_METHOD, /**< OPTIONS method. */ - /** CANCEL method, for cancelling request. */ - PJSIP_CANCEL_METHOD, - - /** ACK method, for acknowledging final response to INVITE. */ - PJSIP_ACK_METHOD, - - /** BYE method, for terminating dialog. */ - PJSIP_BYE_METHOD, - - /** REGISTER method. */ - PJSIP_REGISTER_METHOD, - - /** OPTIONS method, for querying remote capabilities. */ - PJSIP_OPTIONS_METHOD, - - /** Other method, which means that the method name itself will be stored - elsewhere. */ - PJSIP_OTHER_METHOD, + PJSIP_OTHER_METHOD, /**< Other method. */ } pjsip_method_e; @@ -93,6 +80,17 @@ typedef struct pjsip_method } pjsip_method; +/* + * For convenience, standard method structures are defined in the library. + */ +extern const pjsip_method pjsip_invite_method; /**< INVITE structure. */ +extern const pjsip_method pjsip_cancel_method; /**< CANCEL structure. */ +extern const pjsip_method pjsip_ack_method; /**< ACK structure. */ +extern const pjsip_method pjsip_bye_method; /**< BYE structure. */ +extern const pjsip_method pjsip_register_method; /**< REGISTER structure.*/ +extern const pjsip_method pjsip_options_method; /**< OPTIONS structure. */ + + /** * Initialize the method structure from a string. * This function will check whether the method is a known method then set @@ -638,8 +636,8 @@ PJ_DECL(pjsip_msg*) pjsip_msg_create( pj_pool_t *pool, pjsip_msg_type_e type); * @return The header field, or NULL if no header with the specified * type is found. */ -PJ_DECL(void*) pjsip_msg_find_hdr( pjsip_msg *msg, - pjsip_hdr_e type, void *start); +PJ_DECL(void*) pjsip_msg_find_hdr( const pjsip_msg *msg, + pjsip_hdr_e type, const void *start); /** * Find a header in the message by its name. @@ -654,8 +652,9 @@ PJ_DECL(void*) pjsip_msg_find_hdr( pjsip_msg *msg, * @return The header field, or NULL if no header with the specified * type is found. */ -PJ_DECL(void*) pjsip_msg_find_hdr_by_name( pjsip_msg *msg, - const pj_str_t *name, void *start); +PJ_DECL(void*) pjsip_msg_find_hdr_by_name( const pjsip_msg *msg, + const pj_str_t *name, + const void *start); /** * Find and remove a header in the message. @@ -702,7 +701,8 @@ PJ_IDECL(void) pjsip_msg_insert_first_hdr( pjsip_msg *msg, pjsip_hdr *hdr ); * @return The length of the printed characters (in bytes), or NEGATIVE * value if the message is too large for the specified buffer. */ -PJ_DECL(pj_ssize_t) pjsip_msg_print(pjsip_msg *msg, char *buf, pj_size_t size); +PJ_DECL(pj_ssize_t) pjsip_msg_print(const pjsip_msg *msg, + char *buf, pj_size_t size); /** * @} diff --git a/pjsip/include/pjsip/sip_transport.h b/pjsip/include/pjsip/sip_transport.h index 14175dc7..6e6ba428 100644 --- a/pjsip/include/pjsip/sip_transport.h +++ b/pjsip/include/pjsip/sip_transport.h @@ -367,16 +367,21 @@ 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. + * 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(void) pjsip_tx_data_dec_ref( pjsip_tx_data *tdata ); +PJ_DECL(pj_status_t) pjsip_tx_data_dec_ref( 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 ); @@ -542,11 +547,14 @@ struct pjsip_tpfactory /** * Create new outbound connection. + * 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); /* @@ -621,11 +629,11 @@ PJ_DECL(void) pjsip_tpmgr_dump_transports(pjsip_tpmgr *mgr); * Find transport to be used to send message to remote destination. If no * suitable transport is found, a new one will be created. */ -PJ_DECL(pj_status_t) pjsip_tpmgr_alloc_transport( pjsip_tpmgr *mgr, - pjsip_transport_type_e type, - const pj_sockaddr_t *remote, - int addr_len, - pjsip_transport **p_transport ); +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, + pjsip_transport **tp); /** diff --git a/pjsip/include/pjsip/sip_transport_udp.h b/pjsip/include/pjsip/sip_transport_udp.h index d3fd5d30..886f18c6 100644 --- a/pjsip/include/pjsip/sip_transport_udp.h +++ b/pjsip/include/pjsip/sip_transport_udp.h @@ -21,7 +21,7 @@ #include -PJ_DECL +PJ_BEGIN_DECL /** * Start UDP transport. diff --git a/pjsip/include/pjsip/sip_util.h b/pjsip/include/pjsip/sip_util.h index f55cd7e9..ea0fcf3f 100644 --- a/pjsip/include/pjsip/sip_util.h +++ b/pjsip/include/pjsip/sip_util.h @@ -20,6 +20,7 @@ #define __PJSIP_SIP_MISC_H__ #include +#include PJ_BEGIN_DECL @@ -34,6 +35,15 @@ PJ_BEGIN_DECL * request outside a dialog, such as OPTIONS, MESSAGE, etc. To create a request * inside a dialog, application should use #pjsip_dlg_create_request. * + * This function adds the following headers in the request: + * - From, To, Call-ID, and CSeq, + * - Contact header, if contact is specified. + * - A blank Via header. + * - Additional request headers (such as Max-Forwards) which are copied + * from endpoint configuration. + * + * In addition, the function adds a unique tag in the From header. + * * Once a transmit data is created, the reference counter is initialized to 1. * * @param endpt Endpoint instance. @@ -62,7 +72,16 @@ PJ_DECL(pj_status_t) pjsip_endpt_create_request( pjsip_endpoint *endpt, /** * Create an independent request message from the specified headers. This - * function will shallow clone the headers and put them in the request. + * function will clone the headers and put them in the request. + * + * This function adds the following headers in the request: + * - From, To, Call-ID, and CSeq, + * - Contact header, if contact is specified. + * - A blank Via header. + * - Additional request headers (such as Max-Forwards) which are copied + * from endpoint configuration. + * + * In addition, the function adds a unique tag in the From header. * * Once a transmit data is created, the reference counter is initialized to 1. * @@ -91,31 +110,6 @@ pjsip_endpt_create_request_from_hdr( pjsip_endpoint *endpt, const pj_str_t *text, pjsip_tx_data **p_tdata); -/** - * Send outgoing request and initiate UAC transaction for the request. - * This is an auxiliary function to be used by application to send arbitrary - * requests outside a dialog. To send a request within a dialog, application - * should use #pjsip_dlg_send_msg instead. - * - * @param endpt The endpoint instance. - * @param tdata The transmit data to be sent. - * @param timeout Optional timeout for final response to be received, or -1 - * if the transaction should not have a timeout restriction. - * @param token Optional token to be associated with the transaction, and - * to be passed to the callback. - * @param cb Optional callback to be called when the transaction has - * received a final response. The callback will be called with - * the previously registered token and the event that triggers - * the completion of the transaction. - * - * @return PJ_SUCCESS, or the appropriate error code. - */ -PJ_DECL(pj_status_t) pjsip_endpt_send_request( pjsip_endpoint *endpt, - pjsip_tx_data *tdata, - int timeout, - void *token, - void (*cb)(void*,pjsip_event*)); - /** * Construct a minimal response message for the received request. This function * will construct all the Via, Record-Route, Call-ID, From, To, CSeq, and @@ -125,14 +119,16 @@ PJ_DECL(pj_status_t) pjsip_endpt_send_request( pjsip_endpoint *endpt, * * @param endpt The endpoint. * @param rdata The request receive data. - * @param code Status code to be put in the response. + * @param st_code Status code to be put in the response. + * @param st_text Optional status text, or NULL to get the default text. * @param p_tdata Pointer to receive the transmit data. * * @return PJ_SUCCESS, or the appropriate error code. */ PJ_DECL(pj_status_t) pjsip_endpt_create_response( pjsip_endpoint *endpt, const pjsip_rx_data *rdata, - int code, + int st_code, + const pj_str_t *st_text, pjsip_tx_data **p_tdata); /** @@ -143,13 +139,16 @@ PJ_DECL(pj_status_t) pjsip_endpt_create_response( pjsip_endpoint *endpt, * this one. * * @param endpt The endpoint. - * @param tdata On input, this contains the original INVITE request, and on - * output, it contains the ACK message. - * @param rdata The final response message. + * @param tdata This contains the original INVITE request + * @param rdata The final response. + * @param ack The ACK request created. + * + * @return PJ_SUCCESS, or the appropriate error code. */ -PJ_DECL(void) pjsip_endpt_create_ack( pjsip_endpoint *endpt, - pjsip_tx_data *tdata, - const pjsip_rx_data *rdata ); +PJ_DECL(pj_status_t) pjsip_endpt_create_ack( pjsip_endpoint *endpt, + const pjsip_tx_data *tdata, + const pjsip_rx_data *rdata, + pjsip_tx_data **ack); /** @@ -162,25 +161,197 @@ PJ_DECL(void) pjsip_endpt_create_ack( pjsip_endpoint *endpt, * @return PJ_SUCCESS, or the appropriate error code. */ PJ_DECL(pj_status_t) pjsip_endpt_create_cancel( pjsip_endpoint *endpt, - pjsip_tx_data *tdata, + const pjsip_tx_data *tdata, pjsip_tx_data **p_tdata); /** - * Get the address parameters (host, port, flag, TTL, etc) to send the - * response. + * Find which destination to be used to send the request message, based + * on the request URI and Route headers in the message. The procedure + * used here follows the guidelines on sending the request in RFC 3261 + * chapter 8.1.2. + * + * This function may modify the message (request line and Route headers), + * if the Route information specifies strict routing and the request + * URI in the message is different than the calculated target URI. In that + * case, the target URI will be put as the request URI of the request and + * current request URI will be put as the last entry of the Route headers. + * + * @param tdata The transmit data containing the request message. + * @param dest_info On return, it contains information about destination + * host to contact, along with the preferable transport + * type, if any. Caller will then normally proceed with + * resolving this host with server resolution procedure + * described in RFC 3263. + * + * @return PJ_SUCCESS, or the appropriate error code. + */ +PJ_DECL(pj_status_t) pjsip_get_request_addr( pjsip_tx_data *tdata, + pjsip_host_info *dest_info ); + + +/** + * This structure holds the state of outgoing stateless request. + */ +typedef struct pjsip_send_state +{ + /** Application token, which was specified when the function + * #pjsip_endpt_send_request_stateless() is called. + */ + void *token; + + /** Endpoint instance. + */ + pjsip_endpoint *endpt; + + /** Transmit data buffer being sent. + */ + pjsip_tx_data *tdata; + + /** Server addresses resolved. + */ + pjsip_server_addresses addr; + + /** Current server address being tried. + */ + unsigned cur_addr; + + /** Current transport being used. + */ + pjsip_transport *cur_transport; + + /** The application callback which was specified when the function + * #pjsip_endpt_send_request_stateless() was called. + */ + void (*app_cb)(struct pjsip_send_state*, + pj_ssize_t sent, + pj_bool_t *cont); +} pjsip_send_state; + +/** + * Send outgoing request statelessly The function will take care of which + * destination and transport to use based on the information in the message, + * taking care of URI in the request line and Route header. + * + * This function is different than #pjsip_transport_send() in that this + * function adds/modify the Via header as necessary. + * + * @param endpt The endpoint instance. + * @param tdata The transmit data to be sent. + * + * @return PJ_SUCCESS, or the appropriate error code. + */ +PJ_DECL(pj_status_t) +pjsip_endpt_send_request_stateless( pjsip_endpoint *endpt, + pjsip_tx_data *tdata, + void *token, + void (*cb)(pjsip_send_state*, + pj_ssize_t sent, + pj_bool_t *cont)); + +/** + * This structure describes destination information to send response. + * It is initialized by calling #pjsip_get_response_addr(). + * + * If the response message should be sent using transport from which + * the request was received, then transport, addr, and addr_len fields + * are initialized. + * + * The dst_host field is also initialized. It should be used when server + * fails to send the response using the transport from which the request + * was received, or when the transport is NULL, which means server + * must send the response to this address (this situation occurs when + * maddr parameter is set, or when rport param is not set in the request). + */ +typedef struct pjsip_response_addr +{ + pjsip_transport *transport; /**< Immediate transport to be used. */ + pj_sockaddr addr; /**< Immediate address to send to. */ + int addr_len; /**< Address length. */ + pjsip_host_info dst_host; /**< Destination host to contact. */ +} pjsip_response_addr; + +/** + * Determine which address (and transport) to use to send response message + * based on the received request. This function follows the specification + * in section 18.2.2 of RFC 3261 and RFC 3581 for calculating the destination + * address and transport. + * + * The information about destination to send the response will be returned + * in res_addr argument. Please see #pjsip_response_addr for more info. * * @param pool The pool. - * @param tr The transport where the request was received. - * @param via The top-most Via header of the request. - * @param addr The send address concluded from the calculation. + * @param rdata The incoming request received by the server. + * @param res_addr On return, it will be initialized with information about + * destination address and transport to send the response. * * @return zero (PJ_OK) if successfull. */ PJ_DECL(pj_status_t) pjsip_get_response_addr(pj_pool_t *pool, - const pjsip_transport *tr, - const pjsip_via_hdr *via, - pjsip_host_info *addr); + pjsip_rx_data *rdata, + pjsip_response_addr *res_addr); + +/** + * Send response in tdata statelessly. The function will take care of which + * response destination and transport to use based on the information in the + * Via header (such as the presence of rport, symmetric transport, etc.). + * + * This function will create a new ephemeral transport if no existing + * transports can be used to send the message to the destination. The ephemeral + * transport will be destroyed after some period if it is not used to send any + * more messages. + * + * The behavior of this function complies with section 18.2.2 of RFC 3261 + * and RFC 3581. + * + * @param endpt The endpoint instance. + * @param res_addr The information about the address and transport to send + * the response to. Application can get this information + * by calling #pjsip_get_response_addr(). + * @param tdata The response message to be sent. + * @param token Token to be passed back when the callback is called. + * @param cb Optional callback to notify the transmission status + * to application, and to inform whether next address or + * transport will be tried. + * + * @return PJ_SUCCESS if response has been successfully created and + * sent to transport layer, or a non-zero error code. + * However, even when it returns PJ_SUCCESS, there is no + * guarantee that the response has been successfully sent. + */ +PJ_DECL(pj_status_t) pjsip_endpt_send_response( pjsip_endpoint *endpt, + pjsip_response_addr *res_addr, + pjsip_tx_data *tdata, + void *token, + void (*cb)(pjsip_send_state*, + pj_ssize_t sent, + pj_bool_t *cont)); + +/** + * Send outgoing request and initiate UAC transaction for the request. + * This is an auxiliary function to be used by application to send arbitrary + * requests outside a dialog. To send a request within a dialog, application + * should use #pjsip_dlg_send_msg instead. + * + * @param endpt The endpoint instance. + * @param tdata The transmit data to be sent. + * @param timeout Optional timeout for final response to be received, or -1 + * if the transaction should not have a timeout restriction. + * @param token Optional token to be associated with the transaction, and + * to be passed to the callback. + * @param cb Optional callback to be called when the transaction has + * received a final response. The callback will be called with + * the previously registered token and the event that triggers + * the completion of the transaction. + * + * @return PJ_SUCCESS, or the appropriate error code. + */ +PJ_DECL(pj_status_t) pjsip_endpt_send_request( pjsip_endpoint *endpt, + pjsip_tx_data *tdata, + int timeout, + void *token, + void (*cb)(void*,pjsip_event*)); + /** * @} diff --git a/pjsip/include/pjsip_core.h b/pjsip/include/pjsip_core.h index 8ae286a5..9f3c7e9b 100644 --- a/pjsip/include/pjsip_core.h +++ b/pjsip/include/pjsip_core.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include -- cgit v1.2.3