summaryrefslogtreecommitdiff
path: root/pjsip/include/pjsip
diff options
context:
space:
mode:
authorDavid M. Lee <dlee@digium.com>2013-01-07 14:24:28 -0600
committerDavid M. Lee <dlee@digium.com>2013-01-07 14:24:28 -0600
commitf3ab456a17af1c89a6e3be4d20c5944853df1cb0 (patch)
treed00e1a332cd038a6d906a1ea0ac91e1a4458e617 /pjsip/include/pjsip
Import pjproject-2.0.1
Diffstat (limited to 'pjsip/include/pjsip')
-rw-r--r--pjsip/include/pjsip/print_util.h141
-rw-r--r--pjsip/include/pjsip/sip_auth.h519
-rw-r--r--pjsip/include/pjsip/sip_auth_aka.h213
-rw-r--r--pjsip/include/pjsip/sip_auth_msg.h252
-rw-r--r--pjsip/include/pjsip/sip_auth_parser.h73
-rw-r--r--pjsip/include/pjsip/sip_autoconf.h.in39
-rw-r--r--pjsip/include/pjsip/sip_config.h1025
-rw-r--r--pjsip/include/pjsip/sip_dialog.h791
-rw-r--r--pjsip/include/pjsip/sip_endpoint.h584
-rw-r--r--pjsip/include/pjsip/sip_errno.h545
-rw-r--r--pjsip/include/pjsip/sip_event.h231
-rw-r--r--pjsip/include/pjsip/sip_module.h222
-rw-r--r--pjsip/include/pjsip/sip_msg.h2048
-rw-r--r--pjsip/include/pjsip/sip_multipart.h179
-rw-r--r--pjsip/include/pjsip/sip_parser.h416
-rw-r--r--pjsip/include/pjsip/sip_private.h32
-rw-r--r--pjsip/include/pjsip/sip_resolve.h291
-rw-r--r--pjsip/include/pjsip/sip_tel_uri.h84
-rw-r--r--pjsip/include/pjsip/sip_transaction.h414
-rw-r--r--pjsip/include/pjsip/sip_transport.h1406
-rw-r--r--pjsip/include/pjsip/sip_transport_loop.h147
-rw-r--r--pjsip/include/pjsip/sip_transport_tcp.h210
-rw-r--r--pjsip/include/pjsip/sip_transport_tls.h305
-rw-r--r--pjsip/include/pjsip/sip_transport_udp.h235
-rw-r--r--pjsip/include/pjsip/sip_types.h257
-rw-r--r--pjsip/include/pjsip/sip_ua_layer.h162
-rw-r--r--pjsip/include/pjsip/sip_uri.h468
-rw-r--r--pjsip/include/pjsip/sip_util.h861
28 files changed, 12150 insertions, 0 deletions
diff --git a/pjsip/include/pjsip/print_util.h b/pjsip/include/pjsip/print_util.h
new file mode 100644
index 0000000..c27d14a
--- /dev/null
+++ b/pjsip/include/pjsip/print_util.h
@@ -0,0 +1,141 @@
+/* $Id: print_util.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * 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_PRINT_H__
+#define __PJSIP_PRINT_H__
+
+#define copy_advance_check(buf,str) \
+ do { \
+ if ((str).slen >= (endbuf-buf)) return -1; \
+ pj_memcpy(buf, (str).ptr, (str).slen); \
+ buf += (str).slen; \
+ } while (0)
+
+#define copy_advance_pair_check(buf,str1,len1,str2) \
+ do { \
+ if (str2.slen) { \
+ printed = len1+str2.slen; \
+ if (printed >= (endbuf-buf)) return -1; \
+ pj_memcpy(buf,str1,len1); \
+ pj_memcpy(buf+len1, str2.ptr, str2.slen); \
+ buf += printed; \
+ } \
+ } while (0)
+
+#define copy_advance_pair_quote_check(buf,str1,len1,str2,quotebegin,quoteend) \
+ do { \
+ if (str2.slen) { \
+ printed = len1+str2.slen+2; \
+ if (printed >= (endbuf-buf)) return -1; \
+ pj_memcpy(buf,str1,len1); \
+ *(buf+len1)=quotebegin; \
+ pj_memcpy(buf+len1+1, str2.ptr, str2.slen); \
+ *(buf+printed-1) = quoteend; \
+ buf += printed; \
+ } \
+ } while (0)
+
+#define copy_advance_pair_quote(buf,str1,len1,str2,quotebegin,quoteend) \
+ do { \
+ printed = len1+str2.slen+2; \
+ if (printed >= (endbuf-buf)) return -1; \
+ pj_memcpy(buf,str1,len1); \
+ *(buf+len1)=quotebegin; \
+ pj_memcpy(buf+len1+1, str2.ptr, str2.slen); \
+ *(buf+printed-1) = quoteend; \
+ buf += printed; \
+ } while (0)
+
+#define copy_advance_pair_escape(buf,str1,len1,str2,unres) \
+ do { \
+ if (str2.slen) { \
+ if (len1+str2.slen >= (endbuf-buf)) return -1; \
+ pj_memcpy(buf,str1,len1); \
+ printed=pj_strncpy2_escape(buf+len1,&str2,(endbuf-buf-len1),&unres);\
+ if (printed < 0) return -1; \
+ buf += (printed+len1); \
+ } \
+ } while (0)
+
+
+#define copy_advance_no_check(buf,str) \
+ do { \
+ pj_memcpy(buf, (str).ptr, (str).slen); \
+ buf += (str).slen; \
+ } while (0)
+
+#define copy_advance_escape(buf,str,unres) \
+ do { \
+ printed = \
+ pj_strncpy2_escape(buf, &(str), (endbuf-buf), &(unres)); \
+ if (printed < 0) return -1; \
+ buf += printed; \
+ } while (0)
+
+#define copy_advance_pair_no_check(buf,str1,len1,str2) \
+ if (str2.slen) { \
+ pj_memcpy(buf,str1,len1); \
+ pj_memcpy(buf+len1, str2.ptr, str2.slen); \
+ buf += len1+str2.slen; \
+ }
+
+#define copy_advance copy_advance_check
+#define copy_advance_pair copy_advance_pair_check
+
+#define copy_advance_pair_quote_cond(buf,str1,len1,str2,quotebegin,quoteend) \
+ do { \
+ if (str2.slen && *str2.ptr!=quotebegin) \
+ copy_advance_pair_quote(buf,str1,len1,str2,quotebegin,quoteend); \
+ else \
+ copy_advance_pair(buf,str1,len1,str2); \
+ } while (0)
+
+/*
+ * Internal type declarations.
+ */
+typedef void* (*pjsip_hdr_clone_fptr)(pj_pool_t *, const void*);
+typedef int (*pjsip_hdr_print_fptr)(void *hdr, char *buf, pj_size_t len);
+
+typedef struct pjsip_hdr_name_info_t
+{
+ char *name;
+ unsigned name_len;
+ char *sname;
+} pjsip_hdr_name_info_t;
+
+extern const pjsip_hdr_name_info_t pjsip_hdr_names[];
+
+PJ_INLINE(void) init_hdr(void *hptr, pjsip_hdr_e htype, void *vptr)
+{
+ pjsip_hdr *hdr = (pjsip_hdr*) hptr;
+ hdr->type = htype;
+ hdr->name.ptr = pjsip_hdr_names[htype].name;
+ hdr->name.slen = pjsip_hdr_names[htype].name_len;
+ if (pjsip_hdr_names[htype].sname) {
+ hdr->sname.ptr = pjsip_hdr_names[htype].sname;
+ hdr->sname.slen = 1;
+ } else {
+ hdr->sname = hdr->name;
+ }
+ hdr->vptr = (pjsip_hdr_vptr*) vptr;
+ pj_list_init(hdr);
+}
+
+#endif /* __PJSIP_PRINT_H__ */
+
diff --git a/pjsip/include/pjsip/sip_auth.h b/pjsip/include/pjsip/sip_auth.h
new file mode 100644
index 0000000..613e0d5
--- /dev/null
+++ b/pjsip/include/pjsip/sip_auth.h
@@ -0,0 +1,519 @@
+/* $Id: sip_auth.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * 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_AUTH_SIP_AUTH_H__
+#define __PJSIP_AUTH_SIP_AUTH_H__
+
+/**
+ * @file pjsip_auth.h
+ * @brief SIP Authorization Module.
+ */
+
+#include <pjsip/sip_config.h>
+#include <pjsip/sip_auth_msg.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @addtogroup PJSIP_AUTH
+ * @ingroup PJSIP_CORE
+ * @brief Client and server side authentication framework.
+ */
+
+/**
+ * @defgroup PJSIP_AUTH_API Authentication API's
+ * @ingroup PJSIP_AUTH
+ * @brief Structures and functions to perform authentication.
+ * @{
+ */
+
+/** Length of digest string. */
+#define PJSIP_MD5STRLEN 32
+
+
+/** Type of data in the credential information in #pjsip_cred_info. */
+typedef enum pjsip_cred_data_type
+{
+ PJSIP_CRED_DATA_PLAIN_PASSWD=0, /**< Plain text password. */
+ PJSIP_CRED_DATA_DIGEST =1, /**< Hashed digest. */
+
+ PJSIP_CRED_DATA_EXT_AKA =16 /**< Extended AKA info is available */
+
+} pjsip_cred_data_type;
+
+/** Authentication's quality of protection (qop) type. */
+typedef enum pjsip_auth_qop_type
+{
+ PJSIP_AUTH_QOP_NONE, /**< No quality of protection. */
+ PJSIP_AUTH_QOP_AUTH, /**< Authentication. */
+ PJSIP_AUTH_QOP_AUTH_INT, /**< Authentication with integrity protection. */
+ PJSIP_AUTH_QOP_UNKNOWN /**< Unknown protection. */
+} pjsip_auth_qop_type;
+
+
+/**
+ * Type of callback function to create authentication response.
+ * Application can specify this callback in \a cb field of the credential info
+ * (#pjsip_cred_info) and specifying PJSIP_CRED_DATA_DIGEST_CALLBACK as
+ * \a data_type. When this function is called, most of the fields in the
+ * \a auth authentication response will have been filled by the framework.
+ * Application normally should just need to calculate the response digest
+ * of the authentication response.
+ *
+ * @param pool Pool to allocate memory from if application needs to.
+ * @param chal The authentication challenge sent by server in 401
+ * or 401 response, in either Proxy-Authenticate or
+ * WWW-Authenticate header.
+ * @param cred The credential that has been selected by the framework
+ * to authenticate against the challenge.
+ * @param auth The authentication response which application needs to
+ * calculate the response digest.
+ *
+ * @return Application may return non-PJ_SUCCESS to abort the
+ * authentication process. When this happens, the
+ * framework will return failure to the original function
+ * that requested authentication.
+ */
+typedef pj_status_t (*pjsip_cred_cb)(pj_pool_t *pool,
+ const pjsip_digest_challenge *chal,
+ const pjsip_cred_info *cred,
+ const pj_str_t *method,
+ pjsip_digest_credential *auth);
+
+
+/**
+ * This structure describes credential information.
+ * A credential information is a static, persistent information that identifies
+ * username and password required to authorize to a specific realm.
+ *
+ * Note that since PJSIP 0.7.0.1, it is possible to make a credential that is
+ * valid for any realms, by setting the realm to star/wildcard character,
+ * i.e. realm = pj_str("*");.
+ */
+struct pjsip_cred_info
+{
+ pj_str_t realm; /**< Realm. Use "*" to make a credential that
+ can be used to authenticate against any
+ challenges. */
+ pj_str_t scheme; /**< Scheme (e.g. "digest"). */
+ pj_str_t username; /**< User name. */
+ int data_type; /**< Type of data (0 for plaintext passwd). */
+ pj_str_t data; /**< The data, which can be a plaintext
+ password or a hashed digest. */
+
+ /** Extended data */
+ union {
+ /** Digest AKA credential information. Note that when AKA credential
+ * is being used, the \a data field of this #pjsip_cred_info is
+ * not used, but it still must be initialized to an empty string.
+ * Please see \ref PJSIP_AUTH_AKA_API for more information.
+ */
+ struct {
+ pj_str_t k; /**< Permanent subscriber key. */
+ pj_str_t op; /**< Operator variant key. */
+ pj_str_t amf; /**< Authentication Management Field */
+ pjsip_cred_cb cb; /**< Callback to create AKA digest. */
+ } aka;
+
+ } ext;
+};
+
+/**
+ * This structure describes cached value of previously sent Authorization
+ * or Proxy-Authorization header. The authentication framework keeps a list
+ * of this structure and will resend the same header to the same server
+ * as long as the method, uri, and nonce stays the same.
+ */
+typedef struct pjsip_cached_auth_hdr
+{
+ /** Standard list member */
+ PJ_DECL_LIST_MEMBER(struct pjsip_cached_auth_hdr);
+
+ pjsip_method method; /**< To quickly see the method. */
+ pjsip_authorization_hdr *hdr; /**< The cached header. */
+
+} pjsip_cached_auth_hdr;
+
+
+/**
+ * This structure describes authentication information for the specified
+ * realm. Each instance of this structure describes authentication "session"
+ * between this endpoint and remote server. This "session" information is
+ * usefull to keep information that persists for more than one challenge,
+ * such as nonce-count and cnonce value.
+ *
+ * Other than that, this structure also keeps the last authorization headers
+ * that have been sent in the cache list.
+ */
+typedef struct pjsip_cached_auth
+{
+ /** Standard list member */
+ PJ_DECL_LIST_MEMBER(struct pjsip_cached_auth);
+
+ pj_str_t realm; /**< Realm. */
+ pj_bool_t is_proxy; /**< Server type (401/407) */
+ pjsip_auth_qop_type qop_value; /**< qop required by server. */
+ unsigned stale_cnt; /**< Number of stale retry. */
+#if PJSIP_AUTH_QOP_SUPPORT
+ pj_uint32_t nc; /**< Nonce count. */
+ pj_str_t cnonce; /**< Cnonce value. */
+#endif
+ pjsip_www_authenticate_hdr *last_chal; /**< Last challenge seen. */
+#if PJSIP_AUTH_HEADER_CACHING
+ pjsip_cached_auth_hdr cached_hdr;/**< List of cached header for
+ each method. */
+#endif
+
+} pjsip_cached_auth;
+
+
+/**
+ * This structure describes client authentication session preference.
+ * The preference can be set by calling #pjsip_auth_clt_set_prefs().
+ */
+typedef struct pjsip_auth_clt_pref
+{
+ /**
+ * If this flag is set, the authentication client framework will
+ * send an empty Authorization header in each initial request.
+ * Default is no.
+ */
+ pj_bool_t initial_auth;
+
+ /**
+ * Specify the algorithm to use when empty Authorization header
+ * is to be sent for each initial request (see above)
+ */
+ pj_str_t algorithm;
+
+} pjsip_auth_clt_pref;
+
+
+/**
+ * Duplicate a client authentication preference setting.
+ *
+ * @param pool The memory pool.
+ * @param dst Destination client authentication preference.
+ * @param src Source client authentication preference.
+ */
+PJ_DECL(void) pjsip_auth_clt_pref_dup(pj_pool_t *pool,
+ pjsip_auth_clt_pref *dst,
+ const pjsip_auth_clt_pref *src);
+
+
+/**
+ * This structure describes client authentication sessions. It keeps
+ * all the information needed to authorize the client against all downstream
+ * servers.
+ */
+typedef struct pjsip_auth_clt_sess
+{
+ pj_pool_t *pool; /**< Pool to use. */
+ pjsip_endpoint *endpt; /**< Endpoint where this belongs. */
+ pjsip_auth_clt_pref pref; /**< Preference/options. */
+ unsigned cred_cnt; /**< Number of credentials. */
+ pjsip_cred_info *cred_info; /**< Array of credential information*/
+ pjsip_cached_auth cached_auth; /**< Cached authorization info. */
+
+} pjsip_auth_clt_sess;
+
+
+/**
+ * Duplicate a credential info.
+ *
+ * @param pool The memory pool.
+ * @param dst Destination credential.
+ * @param src Source credential.
+ */
+PJ_DECL(void) pjsip_cred_info_dup(pj_pool_t *pool,
+ pjsip_cred_info *dst,
+ const pjsip_cred_info *src);
+
+/**
+ * Compare two credential infos.
+ *
+ * @param cred1 The credential info to compare.
+ * @param cred2 The credential info to compare.
+ *
+ * @return 0 if both credentials are equal.
+ */
+PJ_DECL(int) pjsip_cred_info_cmp(const pjsip_cred_info *cred1,
+ const pjsip_cred_info *cred2);
+
+
+/**
+ * Type of function to lookup credential for the specified name.
+ *
+ * @param pool Pool to initialize the credential info.
+ * @param realm Realm to find the account.
+ * @param acc_name Account name to look for.
+ * @param cred_info The structure to put the credential when it's found.
+ *
+ * @return The function MUST return PJ_SUCCESS when it found
+ * a correct credential for the specified account and
+ * realm. Otherwise it may return PJSIP_EAUTHACCNOTFOUND
+ * or PJSIP_EAUTHACCDISABLED.
+ */
+typedef pj_status_t pjsip_auth_lookup_cred( pj_pool_t *pool,
+ const pj_str_t *realm,
+ const pj_str_t *acc_name,
+ pjsip_cred_info *cred_info );
+
+/** Flag to specify that server is a proxy. */
+#define PJSIP_AUTH_SRV_IS_PROXY 1
+
+/**
+ * This structure describes server authentication information.
+ */
+typedef struct pjsip_auth_srv
+{
+ pj_str_t realm; /**< Realm to serve. */
+ pj_bool_t is_proxy; /**< Will issue 407 instead of 401 */
+ pjsip_auth_lookup_cred *lookup; /**< Lookup function. */
+
+} pjsip_auth_srv;
+
+
+/**
+ * Initialize client authentication session data structure, and set the
+ * session to use pool for its subsequent memory allocation. The argument
+ * options should be set to zero for this PJSIP version.
+ *
+ * @param sess The client authentication session.
+ * @param endpt Endpoint where this session belongs.
+ * @param pool Pool to use.
+ * @param options Must be zero.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_auth_clt_init( pjsip_auth_clt_sess *sess,
+ pjsip_endpoint *endpt,
+ pj_pool_t *pool,
+ unsigned options);
+
+
+/**
+ * Clone client initialization session.
+ *
+ * @param pool Pool to use.
+ * @param sess Structure to put the duplicated session.
+ * @param rhs The client session to be cloned.
+ *
+ * @return PJ_SUCCESS on success;
+ */
+PJ_DECL(pj_status_t) pjsip_auth_clt_clone( pj_pool_t *pool,
+ pjsip_auth_clt_sess *sess,
+ const pjsip_auth_clt_sess *rhs);
+
+/**
+ * Set the credentials to be used during the session. This will duplicate
+ * the specified credentials using client authentication's pool.
+ *
+ * @param sess The client authentication session.
+ * @param cred_cnt Number of credentials.
+ * @param c Array of credentials.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_auth_clt_set_credentials( pjsip_auth_clt_sess *sess,
+ int cred_cnt,
+ const pjsip_cred_info *c);
+
+
+/**
+ * Set the preference for the client authentication session.
+ *
+ * @param sess The client authentication session.
+ * @param p Preference.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_auth_clt_set_prefs(pjsip_auth_clt_sess *sess,
+ const pjsip_auth_clt_pref *p);
+
+
+/**
+ * Get the preference for the client authentication session.
+ *
+ * @param sess The client authentication session.
+ * @param p Pointer to receive the preference.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_auth_clt_get_prefs(pjsip_auth_clt_sess *sess,
+ pjsip_auth_clt_pref *p);
+
+/**
+ * Initialize new request message with authorization headers.
+ * This function will put Authorization/Proxy-Authorization headers to the
+ * outgoing request message. If caching is enabled (PJSIP_AUTH_HEADER_CACHING)
+ * and the session has previously sent Authorization/Proxy-Authorization header
+ * with the same method, then the same Authorization/Proxy-Authorization header
+ * will be resent from the cache only if qop is not present. If the stack is
+ * configured to automatically generate next Authorization/Proxy-Authorization
+ * headers (PJSIP_AUTH_AUTO_SEND_NEXT flag), then new Authorization/Proxy-
+ * Authorization headers are calculated and generated when they are not present
+ * in the case or if authorization session has qop.
+ *
+ * If both PJSIP_AUTH_HEADER_CACHING flag and PJSIP_AUTH_AUTO_SEND_NEXT flag
+ * are not set, this function will do nothing. The stack then will only send
+ * Authorization/Proxy-Authorization to respond 401/407 response.
+ *
+ * @param sess The client authentication session.
+ * @param tdata The request message to be initialized.
+ *
+ * @return PJ_SUCCESS if successfull.
+ */
+PJ_DECL(pj_status_t) pjsip_auth_clt_init_req( pjsip_auth_clt_sess *sess,
+ pjsip_tx_data *tdata );
+
+
+/**
+ * Call this function when a transaction failed with 401 or 407 response.
+ * This function will reinitialize the original request message with the
+ * authentication challenge found in the response message, and add the
+ * new authorization header in the authorization cache.
+ *
+ * Note that upon return the reference counter of the new transmit data
+ * will be set to 1.
+ *
+ * @param sess The client authentication session.
+ * @param rdata The response message containing 401/407 status.
+ * @param old_request The original request message, which will be re-
+ * created with authorization info.
+ * @param new_request Pointer to receive new request message which
+ * will contain all required authorization headers.
+ *
+ * @return PJ_SUCCESS if new request can be successfully
+ * created to respond all the authentication
+ * challenges.
+ */
+PJ_DECL(pj_status_t) pjsip_auth_clt_reinit_req( pjsip_auth_clt_sess *sess,
+ const pjsip_rx_data *rdata,
+ pjsip_tx_data *old_request,
+ pjsip_tx_data **new_request );
+
+/**
+ * Initialize server authorization session data structure to serve the
+ * specified realm and to use lookup_func function to look for the credential
+ * info.
+ *
+ * @param pool Pool used to initialize the authentication server.
+ * @param auth_srv The authentication server structure.
+ * @param realm Realm to be served by the server.
+ * @param lookup Account lookup function.
+ * @param options Options, bitmask of:
+ * - PJSIP_AUTH_SRV_IS_PROXY: to specify that the server
+ * will authorize clients as a proxy server (instead of
+ * as UAS), which means that Proxy-Authenticate will
+ * be used instead of WWW-Authenticate.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_auth_srv_init( pj_pool_t *pool,
+ pjsip_auth_srv *auth_srv,
+ const pj_str_t *realm,
+ pjsip_auth_lookup_cred *lookup,
+ unsigned options );
+
+
+/**
+ * Request the authorization server framework to verify the authorization
+ * information in the specified request in rdata.
+ *
+ * @param auth_srv The server authentication structure.
+ * @param rdata Incoming request to be authenticated.
+ * @param status_code When not null, it will be filled with suitable
+ * status code to be sent to the client.
+ *
+ * @return PJ_SUCCESS if request is successfully authenticated.
+ * Otherwise the function may return one of the
+ * following error codes:
+ * - PJSIP_EAUTHNOAUTH
+ * - PJSIP_EINVALIDAUTHSCHEME
+ * - PJSIP_EAUTHACCNOTFOUND
+ * - PJSIP_EAUTHACCDISABLED
+ * - PJSIP_EAUTHINVALIDREALM
+ * - PJSIP_EAUTHINVALIDDIGEST
+ */
+PJ_DECL(pj_status_t) pjsip_auth_srv_verify( pjsip_auth_srv *auth_srv,
+ pjsip_rx_data *rdata,
+ int *status_code );
+
+
+/**
+ * Add authentication challenge headers to the outgoing response in tdata.
+ * Application may specify its customized nonce and opaque for the challenge,
+ * or can leave the value to NULL to make the function fills them in with
+ * random characters.
+ *
+ * @param auth_srv The server authentication structure.
+ * @param qop Optional qop value.
+ * @param nonce Optional nonce value.
+ * @param opaque Optional opaque value.
+ * @param stale Stale indication.
+ * @param tdata The outgoing response message. The response must have
+ * 401 or 407 response code.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_auth_srv_challenge( pjsip_auth_srv *auth_srv,
+ const pj_str_t *qop,
+ const pj_str_t *nonce,
+ const pj_str_t *opaque,
+ pj_bool_t stale,
+ pjsip_tx_data *tdata);
+
+/**
+ * Helper function to create MD5 digest out of the specified
+ * parameters.
+ *
+ * @param result String to store the response digest. This string
+ * must have been preallocated by caller with the
+ * buffer at least PJSIP_MD5STRLEN (32 bytes) in size.
+ * @param nonce Optional nonce.
+ * @param nc Nonce count.
+ * @param cnonce Optional cnonce.
+ * @param qop Optional qop.
+ * @param uri URI.
+ * @param realm Realm.
+ * @param cred_info Credential info.
+ * @param method SIP method.
+ */
+PJ_DECL(void) pjsip_auth_create_digest(pj_str_t *result,
+ const pj_str_t *nonce,
+ const pj_str_t *nc,
+ const pj_str_t *cnonce,
+ const pj_str_t *qop,
+ const pj_str_t *uri,
+ const pj_str_t *realm,
+ const pjsip_cred_info *cred_info,
+ const pj_str_t *method);
+
+/**
+ * @}
+ */
+
+
+
+PJ_END_DECL
+
+
+#endif /* __PJSIP_AUTH_SIP_AUTH_H__ */
+
diff --git a/pjsip/include/pjsip/sip_auth_aka.h b/pjsip/include/pjsip/sip_auth_aka.h
new file mode 100644
index 0000000..0665bf2
--- /dev/null
+++ b/pjsip/include/pjsip/sip_auth_aka.h
@@ -0,0 +1,213 @@
+/* $Id: sip_auth_aka.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * 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_AUTH_SIP_AUTH_AKA_H__
+#define __PJSIP_AUTH_SIP_AUTH_AKA_H__
+
+/**
+ * @file sip_auth_aka.h
+ * @brief SIP Digest AKA Authorization Module.
+ */
+
+#include <pjsip/sip_auth.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJSIP_AUTH_AKA_API Digest AKAv1 and AKAv2 Authentication API
+ * @ingroup PJSIP_AUTH_API
+ * @brief Digest AKAv1 and AKAv2 Authentication API
+ * @{
+ *
+ * This module implements HTTP digest authentication using Authentication
+ * and Key Agreement (AKA) version 1 and version 2 (AKAv1-MD5 and AKAv2-MD5),
+ * as specified in RFC 3310 and RFC 4169. SIP AKA authentication is used
+ * by 3GPP and IMS systems.
+ *
+ * @section pjsip_aka_using Using Digest AKA Authentication
+ *
+ * Support for digest AKA authentication is currently made optional, so
+ * application needs to declare \a PJSIP_HAS_DIGEST_AKA_AUTH to non-zero
+ * in <tt>config_site.h</tt> to enable AKA support:
+ *
+ @code
+ #define PJSIP_HAS_DIGEST_AKA_AUTH 1
+ @endcode
+
+ *
+ * In addition, application would need to link with <b>libmilenage</b>
+ * library from \a third_party directory.
+ *
+ * Application then specifies digest AKA credential by initializing the
+ * authentication credential as follows:
+ *
+ @code
+
+ pjsip_cred_info cred;
+
+ pj_bzero(&cred, sizeof(cred));
+
+ cred.scheme = pj_str("Digest");
+ cred.realm = pj_str("ims-domain.test");
+ cred.username = pj_str("user@ims-domain.test");
+ cred.data_type = PJSIP_CRED_DATA_PLAIN_PASSWD | PJSIP_CRED_DATA_EXT_AKA;
+ cred.data = pj_str("password");
+
+ // AKA extended info
+ cred.ext.aka.k = pj_str("password");
+ cred.ext.aka.cb = &pjsip_auth_create_aka_response
+
+ @endcode
+ *
+ * Description:
+ * - To support AKA, application adds \a PJSIP_CRED_DATA_EXT_AKA flag in the
+ * \a data_type field. This indicates that extended information specific to
+ * AKA authentication is available in the credential, and that response
+ * digest computation will use the callback function instead of the usual MD5
+ * digest computation.
+ *
+ * - The \a scheme for the credential is "Digest".
+ *
+ * - The \a realm is the expected realm in the challenge. Application may
+ * also specify wildcard realm ("*") if it wishes to respond to any realms
+ * in the challenge.
+ *
+ * - The \a data field is optional. Application may fill this with the password
+ * if it wants to support both MD5 and AKA MD5 in a single credential. The
+ * pjsip_auth_create_aka_response() function will use this field if the
+ * challenge indicates "MD5" as the algorithm instead of "AKAv1-MD5" or
+ * "AKAv2-MD5".
+ *
+ * - The \a ext.aka.k field specifies the permanent subscriber key to be used
+ * for AKA authentication. Application may specify binary password containing
+ * NULL character in this key, since the length of the key is indicated in
+ * the \a slen field of the string.
+ *
+ * - The \a ext.aka.cb field specifies the callback function to calculate the
+ * response digest. Application can specify pjsip_auth_create_aka_response()
+ * in this field to use PJSIP's implementation, but it's free to provide
+ * it's own function.
+ *
+ * - Optionally application may set \a ext.aka.op and \a ext.aka.amf in the
+ * credential to specify AKA Operator variant key and AKA Authentication
+ * Management Field information.
+ */
+
+/**
+ * Length of Authentication Key (AK) in bytes.
+ */
+#define PJSIP_AKA_AKLEN 6
+
+/**
+ * Length of Authentication Management Field (AMF) in bytes.
+ */
+#define PJSIP_AKA_AMFLEN 2
+
+/**
+ * Length of AUTN in bytes.
+ */
+#define PJSIP_AKA_AUTNLEN 16
+
+/**
+ * Length of Confidentiality Key (CK) in bytes.
+ */
+#define PJSIP_AKA_CKLEN 16
+
+/**
+ * Length of Integrity Key (AK) in bytes.
+ */
+#define PJSIP_AKA_IKLEN 16
+
+/**
+ * Length of permanent/subscriber Key (K) in bytes.
+ */
+#define PJSIP_AKA_KLEN 16
+
+/**
+ * Length of AKA authentication code in bytes.
+ */
+#define PJSIP_AKA_MACLEN 8
+
+/**
+ * Length of operator key in bytes.
+ */
+#define PJSIP_AKA_OPLEN 16
+
+/**
+ * Length of random challenge (RAND) in bytes.
+ */
+#define PJSIP_AKA_RANDLEN 16
+
+/**
+ * Length of response digest in bytes.
+ */
+#define PJSIP_AKA_RESLEN 8
+
+/**
+ * Length of sequence number (SQN) in bytes.
+ */
+#define PJSIP_AKA_SQNLEN 6
+
+/**
+ * This function creates MD5, AKAv1-MD5, or AKAv2-MD5 response for
+ * the specified challenge in \a chal, according to the algorithm
+ * specified in the challenge, and based on the information in the
+ * credential \a cred.
+ *
+ * Application may register this function as \a ext.aka.cb field of
+ * #pjsip_cred_info structure to make PJSIP automatically call this
+ * function to calculate the response digest. To do so, it needs to
+ * add \a PJSIP_CRED_DATA_EXT_AKA flag in the \a data_type field of
+ * the credential, and fills up other AKA specific information in
+ * the credential.
+ *
+ * @param pool Pool to allocate memory.
+ * @param chal The authentication challenge sent by server in 401
+ * or 401 response, as either Proxy-Authenticate or
+ * WWW-Authenticate header.
+ * @param cred The credential to be used.
+ * @param method The request method.
+ * @param auth The digest credential where the digest response
+ * will be placed to. Upon calling this function, the
+ * nonce, nc, cnonce, qop, uri, and realm fields of
+ * this structure must have been set by caller. Upon
+ * return, the \a response field will be initialized
+ * by this function.
+ *
+ * @return PJ_SUCCESS if response has been created successfully.
+ */
+PJ_DECL(pj_status_t) pjsip_auth_create_aka_response(
+ pj_pool_t *pool,
+ const pjsip_digest_challenge*chal,
+ const pjsip_cred_info *cred,
+ const pj_str_t *method,
+ pjsip_digest_credential *auth);
+
+
+/**
+ * @}
+ */
+
+
+
+PJ_END_DECL
+
+
+#endif /* __PJSIP_AUTH_SIP_AUTH_AKA_H__ */
+
diff --git a/pjsip/include/pjsip/sip_auth_msg.h b/pjsip/include/pjsip/sip_auth_msg.h
new file mode 100644
index 0000000..ee6da24
--- /dev/null
+++ b/pjsip/include/pjsip/sip_auth_msg.h
@@ -0,0 +1,252 @@
+/* $Id: sip_auth_msg.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * 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_AUTH_SIP_AUTH_MSG_H__
+#define __PJSIP_AUTH_SIP_AUTH_MSG_H__
+
+#include <pjsip/sip_msg.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @addtogroup PJSIP_MSG_HDR
+ * @{
+ */
+
+/**
+ * Common credential structure represents common credential fields
+ * present in Authorization/Proxy-Authorization header.
+ */
+struct pjsip_common_credential
+{
+ pj_str_t realm; /**< Credential's realm. */
+ pjsip_param other_param; /**< Other parameters. */
+};
+
+/**
+ * @see pjsip_common_credential
+ */
+typedef struct pjsip_common_credential pjsip_common_credential;
+
+
+/**
+ * This structure describe credential used in Authorization and
+ * Proxy-Authorization header for digest authentication scheme.
+ */
+struct pjsip_digest_credential
+{
+ pj_str_t realm; /**< Realm of the credential */
+ pjsip_param other_param; /**< Other parameters. */
+ pj_str_t username; /**< Username parameter. */
+ pj_str_t nonce; /**< Nonce parameter. */
+ pj_str_t uri; /**< URI parameter. */
+ pj_str_t response; /**< Response digest. */
+ pj_str_t algorithm; /**< Algorithm. */
+ pj_str_t cnonce; /**< Cnonce. */
+ pj_str_t opaque; /**< Opaque value. */
+ pj_str_t qop; /**< Quality of protection. */
+ pj_str_t nc; /**< Nonce count. */
+};
+
+/**
+ * @see pjsip_digest_credential
+ */
+typedef struct pjsip_digest_credential pjsip_digest_credential;
+
+/**
+ * This structure describe credential used in Authorization and
+ * Proxy-Authorization header for PGP authentication scheme.
+ */
+struct pjsip_pgp_credential
+{
+ pj_str_t realm; /**< Realm. */
+ pjsip_param other_param; /**< Other parameters. */
+ pj_str_t version; /**< Version parameter. */
+ pj_str_t signature; /**< Signature parameter. */
+ pj_str_t signed_by; /**< Signed by parameter. */
+ pj_str_t nonce; /**< Nonce parameter. */
+};
+
+/**
+ * @see pjsip_pgp_credential
+ */
+typedef struct pjsip_pgp_credential pjsip_pgp_credential;
+
+/**
+ * This structure describes SIP Authorization header (and also SIP
+ * Proxy-Authorization header).
+ */
+struct pjsip_authorization_hdr
+{
+ /** Standard header fiends. */
+ PJSIP_DECL_HDR_MEMBER(struct pjsip_authorization_hdr);
+
+ /** Authorization scheme. */
+ pj_str_t scheme;
+
+ /** Type of credentials, depending on the scheme. */
+ union
+ {
+ pjsip_common_credential common; /**< Common fields. */
+ pjsip_digest_credential digest; /**< Digest credentials. */
+ pjsip_pgp_credential pgp; /**< PGP credentials. */
+ } credential;
+};
+
+/**
+ * @see pjsip_authorization_hdr.
+ */
+typedef struct pjsip_authorization_hdr pjsip_authorization_hdr;
+
+/** SIP Proxy-Authorization header shares the same structure as SIP
+ Authorization header.
+ */
+typedef struct pjsip_authorization_hdr pjsip_proxy_authorization_hdr;
+
+/**
+ * Create SIP Authorization header.
+ * @param pool Pool where memory will be allocated from.
+ * @return SIP Authorization header.
+ */
+PJ_DECL(pjsip_authorization_hdr*)
+pjsip_authorization_hdr_create(pj_pool_t *pool);
+
+/**
+ * Create SIP Proxy-Authorization header.
+ * @param pool Pool where memory will be allocated from.
+ * @return SIP Proxy-Authorization header.
+ */
+PJ_DECL(pjsip_proxy_authorization_hdr*)
+pjsip_proxy_authorization_hdr_create(pj_pool_t *pool);
+
+
+/**
+ * This structure describes common fields in authentication challenge
+ * headers (WWW-Authenticate and Proxy-Authenticate).
+ */
+struct pjsip_common_challenge
+{
+ pj_str_t realm; /**< Realm for the challenge. */
+ pjsip_param other_param; /**< Other parameters. */
+};
+
+/**
+ * @see pjsip_common_challenge
+ */
+typedef struct pjsip_common_challenge pjsip_common_challenge;
+
+/**
+ * This structure describes authentication challenge used in Proxy-Authenticate
+ * or WWW-Authenticate for digest authentication scheme.
+ */
+struct pjsip_digest_challenge
+{
+ pj_str_t realm; /**< Realm for the challenge. */
+ pjsip_param other_param; /**< Other parameters. */
+ pj_str_t domain; /**< Domain. */
+ pj_str_t nonce; /**< Nonce challenge. */
+ pj_str_t opaque; /**< Opaque value. */
+ int stale; /**< Stale parameter. */
+ pj_str_t algorithm; /**< Algorithm parameter. */
+ pj_str_t qop; /**< Quality of protection. */
+};
+
+/**
+ * @see pjsip_digest_challenge
+ */
+typedef struct pjsip_digest_challenge pjsip_digest_challenge;
+
+/**
+ * This structure describes authentication challenge used in Proxy-Authenticate
+ * or WWW-Authenticate for PGP authentication scheme.
+ */
+struct pjsip_pgp_challenge
+{
+ pj_str_t realm; /**< Realm for the challenge. */
+ pjsip_param other_param; /**< Other parameters. */
+ pj_str_t version; /**< PGP version. */
+ pj_str_t micalgorithm; /**< micalgorithm parameter. */
+ pj_str_t pubalgorithm; /**< pubalgorithm parameter. */
+ pj_str_t nonce; /**< Nonce challenge. */
+};
+
+/**
+ * @see pjsip_pgp_challenge
+ */
+typedef struct pjsip_pgp_challenge pjsip_pgp_challenge;
+
+/**
+ * This structure describe SIP WWW-Authenticate header (Proxy-Authenticate
+ * header also uses the same structure).
+ */
+struct pjsip_www_authenticate_hdr
+{
+ /** Standard header fields. */
+ PJSIP_DECL_HDR_MEMBER(struct pjsip_www_authenticate_hdr);
+
+ /** Authentication scheme */
+ pj_str_t scheme;
+
+ /** This union contains structures that are only relevant
+ depending on the value of the scheme being used.
+ */
+ union
+ {
+ pjsip_common_challenge common; /**< Common fields. */
+ pjsip_digest_challenge digest; /**< Digest challenge. */
+ pjsip_pgp_challenge pgp; /**< PGP challenge. */
+ } challenge;
+};
+
+/**
+ * WWW-Authenticate header.
+ */
+typedef struct pjsip_www_authenticate_hdr pjsip_www_authenticate_hdr;
+
+/**
+ * Proxy-Authenticate header.
+ */
+typedef struct pjsip_www_authenticate_hdr pjsip_proxy_authenticate_hdr;
+
+
+/**
+ * Create SIP WWW-Authenticate header.
+ *
+ * @param pool Pool where memory will be allocated from.
+ * @return SIP WWW-Authenticate header.
+ */
+PJ_DECL(pjsip_www_authenticate_hdr*)
+pjsip_www_authenticate_hdr_create(pj_pool_t *pool);
+
+/**
+ * Create SIP Proxy-Authenticate header.
+ *
+ * @param pool Pool where memory will be allocated from.
+ * @return SIP Proxy-Authenticate header.
+ */
+PJ_DECL(pjsip_proxy_authenticate_hdr*)
+pjsip_proxy_authenticate_hdr_create(pj_pool_t *pool);
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+#endif /* __PJSIP_AUTH_SIP_AUTH_MSG_H__ */
diff --git a/pjsip/include/pjsip/sip_auth_parser.h b/pjsip/include/pjsip/sip_auth_parser.h
new file mode 100644
index 0000000..703c52f
--- /dev/null
+++ b/pjsip/include/pjsip/sip_auth_parser.h
@@ -0,0 +1,73 @@
+/* $Id: sip_auth_parser.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * 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_AUTH_SIP_AUTH_PARSER_H__
+#define __PJSIP_AUTH_SIP_AUTH_PARSER_H__
+
+/**
+ * @file sip_auth_parser.h
+ * @brief SIP Authorization Parser Module.
+ */
+
+#include <pj/types.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * Initialize and register authorization parser module.
+ * This will register parser handler for various Authorization related headers
+ * such as Authorization, WWW-Authenticate, Proxy-Authorizization, and
+ * Proxy-Authenticate headers.
+ *
+ * This function is called automatically by the main SIP parser.
+ *
+ * @return PJ_SUCCESS or the appropriate status code.
+ */
+PJ_DECL(pj_status_t) pjsip_auth_init_parser(void);
+
+/**
+ * DeInitialize authorization parser module.
+ */
+PJ_DECL(void) pjsip_auth_deinit_parser();
+
+
+
+extern const pj_str_t pjsip_USERNAME_STR, /**< "username" string const. */
+ pjsip_REALM_STR, /**< "realm" string const. */
+ pjsip_NONCE_STR, /**< "nonce" string const. */
+ pjsip_URI_STR, /**< "uri" string const. */
+ pjsip_RESPONSE_STR, /**< "response" string const. */
+ pjsip_ALGORITHM_STR,/**< "algorithm" string const. */
+ pjsip_DOMAIN_STR, /**< "domain" string const. */
+ pjsip_STALE_STR, /**< "stale" string const. */
+ pjsip_QOP_STR, /**< "qop" string const. */
+ pjsip_CNONCE_STR, /**< "cnonce" string const. */
+ pjsip_OPAQUE_STR, /**< "opaque" string const. */
+ pjsip_NC_STR, /**< "nc" string const. */
+ pjsip_TRUE_STR, /**< "true" string const. */
+ pjsip_FALSE_STR, /**< "false" string const. */
+ pjsip_DIGEST_STR, /**< "digest" string const. */
+ pjsip_PGP_STR, /**< "pgp" string const. */
+ pjsip_MD5_STR, /**< "md5" string const. */
+ pjsip_AUTH_STR; /**< "auth" string const. */
+
+PJ_END_DECL
+
+#endif /* __PJSIP_AUTH_SIP_AUTH_PARSER_H__ */
+
diff --git a/pjsip/include/pjsip/sip_autoconf.h.in b/pjsip/include/pjsip/sip_autoconf.h.in
new file mode 100644
index 0000000..6cae772
--- /dev/null
+++ b/pjsip/include/pjsip/sip_autoconf.h.in
@@ -0,0 +1,39 @@
+/* $Id: sip_autoconf.h.in 3295 2010-08-25 12:51:29Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 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_AUTOCONF_H__
+#define __PJSIP_SIP_AUTOCONF_H__
+
+/**
+ * @file sip_autoconf.h
+ * @brief Describes operating system specifics (automatically detected by
+ * autoconf)
+ */
+
+/*
+ * Enable/disable TLS transport, as configured by autoconf.
+ * But only do this if user doesn't explicitly configure in pj/config_site.h.
+ */
+/* Since 1.5, the default setting will follow PJ_HAS_SSL_SOCK setting. */
+//#ifndef PJSIP_HAS_TLS_TRANSPORT
+//#undef PJSIP_HAS_TLS_TRANSPORT
+//#endif
+
+#endif /* __PJSIP_SIP_AUTOCONF_H__ */
+
diff --git a/pjsip/include/pjsip/sip_config.h b/pjsip/include/pjsip/sip_config.h
new file mode 100644
index 0000000..9035b1e
--- /dev/null
+++ b/pjsip/include/pjsip/sip_config.h
@@ -0,0 +1,1025 @@
+/* $Id: sip_config.h 4172 2012-06-19 14:35:18Z nanang $ */
+/*
+ * 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_CONFIG_H__
+#define __PJSIP_SIP_CONFIG_H__
+
+/**
+ * @file sip_config.h
+ * @brief Compile time configuration.
+ */
+#include <pj/types.h>
+
+/**
+ * @defgroup PJSIP_CORE Core SIP Library
+ * @brief The core framework from which all other SIP components depends on.
+ *
+ * The PJSIP Core library only provides transport framework, event
+ * dispatching/module framework, and SIP message representation and
+ * parsing. It doesn't do anything usefull in itself!
+ *
+ * If application wants the stack to do anything usefull at all,
+ * it must registers @ref PJSIP_MOD to the core library. Examples
+ * of modules are @ref PJSIP_TRANSACT and @ref PJSUA_UA.
+ */
+
+/**
+ * @defgroup PJSIP_BASE Base Types
+ * @ingroup PJSIP_CORE
+ * @brief Basic PJSIP types and configurations.
+ */
+
+/**
+ * @defgroup PJSIP_CONFIG PJSIP Configurations/Settings
+ * @ingroup PJSIP_BASE
+ * @brief PJSIP compile time configurations.
+ * @{
+ */
+
+/*
+ * Include sip_autoconf.h if autoconf is used (PJ_AUTOCONF is set)
+ */
+#if defined(PJ_AUTOCONF)
+# include <pjsip/sip_autoconf.h>
+#endif
+
+PJ_BEGIN_DECL
+
+/**
+ * This structure describes PJSIP run-time configurations/settings.
+ * Application may use #pjsip_cfg() function to modify the settings
+ * before creating the stack.
+ */
+typedef struct pjsip_cfg_t
+{
+ /** Global settings. */
+ struct {
+ /**
+ * Specify port number should be allowed to appear in To and From
+ * header. Note that RFC 3261 disallow this, see Table 1 in section
+ * 19.1.1 of the RFC. Default is PJSIP_ALLOW_PORT_IN_FROMTO_HDR.
+ */
+ pj_bool_t allow_port_in_fromto_hdr;
+
+ /**
+ * Disable rport in request.
+ */
+ pj_bool_t disable_rport;
+
+ /**
+ * Disable automatic switching from UDP to TCP if outgoing request
+ * is greater than 1300 bytes. See PJSIP_DONT_SWITCH_TO_TCP.
+ */
+ pj_bool_t disable_tcp_switch;
+
+ } endpt;
+
+ /** Transaction layer settings. */
+ struct {
+
+ /** Maximum number of transactions. The value is initialized with
+ * PJSIP_MAX_TSX_COUNT
+ */
+ unsigned max_count;
+
+ /* Timeout values: */
+
+ /** Transaction T1 timeout, in msec. Default value is PJSIP_T1_TIMEOUT
+ */
+ unsigned t1;
+
+ /** Transaction T2 timeout, in msec. Default value is PJSIP_T2_TIMEOUT
+ */
+ unsigned t2;
+
+ /** Transaction completed timer for non-INVITE, in msec. Default value
+ * is PJSIP_T4_TIMEOUT
+ */
+ unsigned t4;
+
+ /** Transaction completed timer for INVITE, in msec. Default value is
+ * PJSIP_TD_TIMEOUT.
+ */
+ unsigned td;
+
+ } tsx;
+
+ /* Dialog layer settings .. TODO */
+
+ /** Client registration settings. */
+ struct {
+ /**
+ * Specify whether client registration should check for its
+ * registered contact in Contact header of successful REGISTER
+ * response to determine whether registration has been successful.
+ * This setting may be disabled if non-compliant registrar is unable
+ * to return correct Contact header.
+ *
+ * Default is PJSIP_REGISTER_CLIENT_CHECK_CONTACT
+ */
+ pj_bool_t check_contact;
+
+ /**
+ * Specify whether client registration should add "x-uid" extension
+ * parameter in all Contact URIs that it registers to assist the
+ * matching of Contact URIs in the 200/OK REGISTER response, in
+ * case the registrar is unable to return exact Contact URI in the
+ * 200/OK response.
+ *
+ * Default is PJSIP_REGISTER_CLIENT_ADD_XUID_PARAM.
+ */
+ pj_bool_t add_xuid_param;
+
+ } regc;
+
+} pjsip_cfg_t;
+
+
+#ifdef PJ_DLL
+/**
+ * Get pjsip configuration instance. Application may modify the
+ * settings before creating the SIP endpoint and modules.
+ *
+ * @return Configuration instance.
+ */
+PJ_DECL(pjsip_cfg_t*) pjsip_cfg(void);
+
+#else /* PJ_DLL */
+
+extern pjsip_cfg_t pjsip_sip_cfg_var;
+
+/**
+ * Get pjsip configuration instance. Application may modify the
+ * settings before creating the SIP endpoint and modules.
+ *
+ * @return Configuration instance.
+ */
+PJ_INLINE(pjsip_cfg_t*) pjsip_cfg(void)
+{
+ return &pjsip_sip_cfg_var;
+}
+
+#endif /* PJ_DLL */
+
+
+/**
+ * Specify maximum transaction count in transaction hash table.
+ * For efficiency, the value should be 2^n-1 since it will be
+ * rounded up to 2^n.
+ *
+ * Default value is 1023
+ */
+#ifndef PJSIP_MAX_TSX_COUNT
+# define PJSIP_MAX_TSX_COUNT (1024-1)
+#endif
+
+/**
+ * Specify maximum number of dialogs in the dialog hash table.
+ * For efficiency, the value should be 2^n-1 since it will be
+ * rounded up to 2^n.
+ *
+ * Default value is 511.
+ */
+#ifndef PJSIP_MAX_DIALOG_COUNT
+# define PJSIP_MAX_DIALOG_COUNT (512-1)
+#endif
+
+
+/**
+ * Specify maximum number of transports.
+ * Default value is equal to maximum number of handles in ioqueue.
+ * See also PJSIP_TPMGR_HTABLE_SIZE.
+ */
+#ifndef PJSIP_MAX_TRANSPORTS
+# define PJSIP_MAX_TRANSPORTS (PJ_IOQUEUE_MAX_HANDLES)
+#endif
+
+
+/**
+ * Transport manager hash table size (must be 2^n-1).
+ * See also PJSIP_MAX_TRANSPORTS
+ */
+#ifndef PJSIP_TPMGR_HTABLE_SIZE
+# define PJSIP_TPMGR_HTABLE_SIZE 31
+#endif
+
+
+/**
+ * Specify maximum URL size.
+ * This constant is used mainly when printing the URL for logging purpose
+ * only.
+ */
+#ifndef PJSIP_MAX_URL_SIZE
+# define PJSIP_MAX_URL_SIZE 256
+#endif
+
+
+/**
+ * Specify maximum number of modules.
+ * This mainly affects the size of mod_data array in various components.
+ */
+#ifndef PJSIP_MAX_MODULE
+# define PJSIP_MAX_MODULE 32
+#endif
+
+
+/**
+ * Maximum packet length. We set it more than MTU since a SIP PDU
+ * containing presence information can be quite large (>1500).
+ */
+#ifndef PJSIP_MAX_PKT_LEN
+# define PJSIP_MAX_PKT_LEN 4000
+#endif
+
+
+/**
+ * RFC 3261 section 18.1.1:
+ * If a request is within 200 bytes of the path MTU, or if it is larger
+ * than 1300 bytes and the path MTU is unknown, the request MUST be sent
+ * using an RFC 2914 [43] congestion controlled transport protocol, such
+ * as TCP.
+ *
+ * Disable the behavior of automatic switching to TCP whenever UDP packet
+ * size exceeds the threshold defined in PJSIP_UDP_SIZE_THRESHOLD.
+ *
+ * This option can also be controlled at run-time by the \a disable_tcp_switch
+ * setting in pjsip_cfg_t.
+ *
+ * Default is 0 (no).
+ */
+#ifndef PJSIP_DONT_SWITCH_TO_TCP
+# define PJSIP_DONT_SWITCH_TO_TCP 0
+#endif
+
+
+/**
+ * This setting controls the threshold of the UDP packet, which if it's
+ * larger than this value the request will be sent with TCP. This setting
+ * is useful only when PJSIP_DONT_SWITCH_TO_TCP is set to 0.
+ *
+ * Default is 1300 bytes.
+ */
+#ifndef PJSIP_UDP_SIZE_THRESHOLD
+# define PJSIP_UDP_SIZE_THRESHOLD 1300
+#endif
+
+
+/**
+ * Encode SIP headers in their short forms to reduce size. By default,
+ * SIP headers in outgoing messages will be encoded in their full names.
+ * If this option is enabled, then SIP headers for outgoing messages
+ * will be encoded in their short forms, to reduce message size.
+ * Note that this does not affect the ability of PJSIP to parse incoming
+ * SIP messages, as the parser always supports parsing both the long
+ * and short version of the headers.
+ *
+ * Note that there is also an undocumented variable defined in sip_msg.c
+ * to control whether compact form should be used for encoding SIP
+ * headers. The default value of this variable is PJSIP_ENCODE_SHORT_HNAME.
+ * To change PJSIP behavior during run-time, application can use the
+ * following construct:
+ *
+ \verbatim
+ extern pj_bool_t pjsip_use_compact_form;
+
+ // enable compact form
+ pjsip_use_compact_form = PJ_TRUE;
+ \endverbatim
+ *
+ * Default is 0 (no)
+ */
+#ifndef PJSIP_ENCODE_SHORT_HNAME
+# define PJSIP_ENCODE_SHORT_HNAME 0
+#endif
+
+
+/**
+ * Send Allow header in dialog establishing requests?
+ * RFC 3261 Allow header SHOULD be included in dialog establishing
+ * requests to inform remote agent about which SIP requests are
+ * allowed within dialog.
+ *
+ * Note that there is also an undocumented variable defined in sip_dialog.c
+ * to control whether Allow header should be included. The default value
+ * of this variable is PJSIP_INCLUDE_ALLOW_HDR_IN_DLG.
+ * To change PJSIP behavior during run-time, application can use the
+ * following construct:
+ *
+ \verbatim
+ extern pj_bool_t pjsip_include_allow_hdr_in_dlg;
+
+ // do not transmit Allow header
+ pjsip_include_allow_hdr_in_dlg = PJ_FALSE;
+ \endverbatim
+ *
+ * Default is 1 (Yes)
+ */
+#ifndef PJSIP_INCLUDE_ALLOW_HDR_IN_DLG
+# define PJSIP_INCLUDE_ALLOW_HDR_IN_DLG 1
+#endif
+
+
+/**
+ * Allow SIP modules removal or insertions during operation?
+ * If yes, then locking will be employed when endpoint need to
+ * access module.
+ */
+#ifndef PJSIP_SAFE_MODULE
+# define PJSIP_SAFE_MODULE 1
+#endif
+
+
+/**
+ * Perform Via sent-by checking as specified in RFC 3261 Section 18.1.2,
+ * which says that UAC MUST silently discard responses with Via sent-by
+ * containing values that the UAC doesn't recognize as its transport
+ * address.
+ *
+ * In PJSIP, this will cause response to be discarded and a message is
+ * written to the log, saying something like:
+ * "Dropping response Response msg 200/INVITE/cseq=608594373 (rdata00A99EF4)
+ * from 1.2.3.4:5060 because sent-by is mismatch"
+ *
+ * The default behavior is yes, but when the UA supports IP address change
+ * for the SIP transport, it will need to turn this checking off since
+ * when the transport address is changed between request is sent and
+ * response is received, the response will be discarded since its Via
+ * sent-by now contains address that is different than the transport
+ * address.
+ */
+#ifndef PJSIP_CHECK_VIA_SENT_BY
+# define PJSIP_CHECK_VIA_SENT_BY 1
+#endif
+
+
+/**
+ * If non-zero, SIP parser will unescape the escape characters ('%')
+ * in the original message, which means that it will modify the
+ * original message. Otherwise the parser will create a copy of
+ * the string and store the unescaped string to the new location.
+ *
+ * Unescaping in-place is faster, but less elegant (and it may
+ * break certain applications). So normally it's disabled, unless
+ * when benchmarking (to show off big performance).
+ *
+ * Default: 0
+ */
+#ifndef PJSIP_UNESCAPE_IN_PLACE
+# define PJSIP_UNESCAPE_IN_PLACE 0
+#endif
+
+
+/**
+ * Specify port number should be allowed to appear in To and From
+ * header. Note that RFC 3261 disallow this, see Table 1 in section
+ * 19.1.1 of the RFC. This setting can also be altered at run-time
+ * via pjsip_cfg setting, see pjsip_cfg_t.allow_port_in_fromto_hdr
+ * field.
+ *
+ * Default: 0
+ */
+#ifndef PJSIP_ALLOW_PORT_IN_FROMTO_HDR
+# define PJSIP_ALLOW_PORT_IN_FROMTO_HDR 0
+#endif
+
+/**
+ * This macro controls maximum numbers of ioqueue events to be processed
+ * in a single pjsip_endpt_handle_events() poll. When PJSIP detects that
+ * there are probably more events available from the network and total
+ * events so far is less than this value, PJSIP will call pj_ioqueue_poll()
+ * again to get more events.
+ *
+ * Value 1 works best for ioqueue with select() back-end, while for IOCP it is
+ * probably best to set this value equal to PJSIP_MAX_TIMED_OUT_ENTRIES
+ * since IOCP only processes one event at a time.
+ *
+ * Default: 1
+ */
+#ifndef PJSIP_MAX_NET_EVENTS
+# define PJSIP_MAX_NET_EVENTS 1
+#endif
+
+
+/**
+ * Max entries to process in timer heap per poll.
+ *
+ * Default: 10
+ */
+#ifndef PJSIP_MAX_TIMED_OUT_ENTRIES
+# define PJSIP_MAX_TIMED_OUT_ENTRIES 10
+#endif
+
+
+/**
+ * Idle timeout interval to be applied to outgoing transports (i.e. client
+ * side) with no usage before the transport is destroyed. Value is in
+ * seconds.
+ *
+ * Note that if the value is put lower than 33 seconds, it may cause some
+ * pjsip test units to fail. See the comment on the following link:
+ * https://trac.pjsip.org/repos/ticket/1465#comment:4
+ *
+ * Default: 33
+ */
+#ifndef PJSIP_TRANSPORT_IDLE_TIME
+# define PJSIP_TRANSPORT_IDLE_TIME 33
+#endif
+
+
+/**
+ * Idle timeout interval to be applied to incoming transports (i.e. server
+ * side) with no usage before the transport is destroyed. Server typically
+ * should let client close the connection, hence set this interval to a large
+ * value. Value is in seconds.
+ *
+ * Default: 600
+ */
+#ifndef PJSIP_TRANSPORT_SERVER_IDLE_TIME
+# define PJSIP_TRANSPORT_SERVER_IDLE_TIME 600
+#endif
+
+
+/**
+ * Maximum number of usages for a transport before a new transport is
+ * created. This only applies for ephemeral transports such as TCP.
+ *
+ * Currently this is not used.
+ *
+ * Default: -1
+ */
+#ifndef PJSIP_MAX_TRANSPORT_USAGE
+# define PJSIP_MAX_TRANSPORT_USAGE ((unsigned)-1)
+#endif
+
+
+/**
+ * The TCP incoming connection backlog number to be set in accept().
+ *
+ * Default: 5
+ *
+ * @see PJSIP_TLS_TRANSPORT_BACKLOG
+ */
+#ifndef PJSIP_TCP_TRANSPORT_BACKLOG
+# define PJSIP_TCP_TRANSPORT_BACKLOG 5
+#endif
+
+
+/**
+ * Set the interval to send keep-alive packet for TCP transports.
+ * If the value is zero, keep-alive will be disabled for TCP.
+ *
+ * Default: 90 (seconds)
+ *
+ * @see PJSIP_TCP_KEEP_ALIVE_DATA
+ */
+#ifndef PJSIP_TCP_KEEP_ALIVE_INTERVAL
+# define PJSIP_TCP_KEEP_ALIVE_INTERVAL 90
+#endif
+
+
+/**
+ * Set the payload of the TCP keep-alive packet.
+ *
+ * Default: CRLF
+ */
+#ifndef PJSIP_TCP_KEEP_ALIVE_DATA
+# define PJSIP_TCP_KEEP_ALIVE_DATA { "\r\n\r\n", 4 }
+#endif
+
+
+/**
+ * Set the interval to send keep-alive packet for TLS transports.
+ * If the value is zero, keep-alive will be disabled for TLS.
+ *
+ * Default: 90 (seconds)
+ *
+ * @see PJSIP_TLS_KEEP_ALIVE_DATA
+ */
+#ifndef PJSIP_TLS_KEEP_ALIVE_INTERVAL
+# define PJSIP_TLS_KEEP_ALIVE_INTERVAL 90
+#endif
+
+
+/**
+ * Set the payload of the TLS keep-alive packet.
+ *
+ * Default: CRLF
+ */
+#ifndef PJSIP_TLS_KEEP_ALIVE_DATA
+# define PJSIP_TLS_KEEP_ALIVE_DATA { "\r\n\r\n", 4 }
+#endif
+
+
+/**
+ * This macro specifies whether full DNS resolution should be used.
+ * When enabled, #pjsip_resolve() will perform asynchronous DNS SRV and
+ * A (or AAAA, when IPv6 is supported) resolution to resolve the SIP
+ * domain.
+ *
+ * Note that even when this setting is enabled, asynchronous DNS resolution
+ * will only be done when application calls #pjsip_endpt_create_resolver(),
+ * configure the nameservers with pj_dns_resolver_set_ns(), and configure
+ * the SIP endpoint's DNS resolver with #pjsip_endpt_set_resolver(). If
+ * these steps are not followed, the domain will be resolved with normal
+ * pj_gethostbyname() function.
+ *
+ * Turning off this setting will save the footprint by about 16KB, since
+ * it should also exclude dns.o and resolve.o from PJLIB-UTIL.
+ *
+ * Default: 1 (enabled)
+ *
+ * @see PJSIP_MAX_RESOLVED_ADDRESSES
+ */
+#ifndef PJSIP_HAS_RESOLVER
+# define PJSIP_HAS_RESOLVER 1
+#endif
+
+
+/**
+ * Maximum number of addresses returned by the resolver. The number here
+ * will slightly affect stack usage, since each entry will occupy about
+ * 32 bytes of stack memory.
+ *
+ * Default: 8
+ *
+ * @see PJSIP_HAS_RESOLVER
+ */
+#ifndef PJSIP_MAX_RESOLVED_ADDRESSES
+# define PJSIP_MAX_RESOLVED_ADDRESSES 8
+#endif
+
+
+/**
+ * Enable TLS SIP transport support. For most systems this means that
+ * OpenSSL must be installed.
+ *
+ * Default: follow PJ_HAS_SSL_SOCK setting, which is 0 (disabled) by default.
+ */
+#ifndef PJSIP_HAS_TLS_TRANSPORT
+# define PJSIP_HAS_TLS_TRANSPORT PJ_HAS_SSL_SOCK
+#endif
+
+
+/**
+ * The TLS pending incoming connection backlog number to be set in accept().
+ *
+ * Default: 5
+ *
+ * @see PJSIP_TCP_TRANSPORT_BACKLOG
+ */
+#ifndef PJSIP_TLS_TRANSPORT_BACKLOG
+# define PJSIP_TLS_TRANSPORT_BACKLOG 5
+#endif
+
+
+
+/* Endpoint. */
+#define PJSIP_MAX_TIMER_COUNT (2*pjsip_cfg()->tsx.max_count + \
+ 2*PJSIP_MAX_DIALOG_COUNT)
+
+/**
+ * Initial memory block for the endpoint.
+ */
+#ifndef PJSIP_POOL_LEN_ENDPT
+# define PJSIP_POOL_LEN_ENDPT (4000)
+#endif
+
+/**
+ * Memory increment for endpoint.
+ */
+#ifndef PJSIP_POOL_INC_ENDPT
+# define PJSIP_POOL_INC_ENDPT (4000)
+#endif
+
+
+/* Transport related constants. */
+
+/**
+ * Initial memory block for rdata.
+ */
+#ifndef PJSIP_POOL_RDATA_LEN
+# define PJSIP_POOL_RDATA_LEN 4000
+#endif
+
+/**
+ * Memory increment for rdata.
+ */
+#ifndef PJSIP_POOL_RDATA_INC
+# define PJSIP_POOL_RDATA_INC 4000
+#endif
+
+#define PJSIP_POOL_LEN_TRANSPORT 512
+#define PJSIP_POOL_INC_TRANSPORT 512
+
+/**
+ * Initial memory block size for tdata.
+ */
+#ifndef PJSIP_POOL_LEN_TDATA
+# define PJSIP_POOL_LEN_TDATA 4000
+#endif
+
+/**
+ * Memory increment for tdata.
+ */
+#ifndef PJSIP_POOL_INC_TDATA
+# define PJSIP_POOL_INC_TDATA 4000
+#endif
+
+/**
+ * Initial memory size for UA layer
+ */
+#ifndef PJSIP_POOL_LEN_UA
+# define PJSIP_POOL_LEN_UA 512
+#endif
+
+/**
+ * Memory increment for UA layer.
+ */
+#ifndef PJSIP_POOL_INC_UA
+# define PJSIP_POOL_INC_UA 512
+#endif
+
+#define PJSIP_MAX_FORWARDS_VALUE 70
+
+#define PJSIP_RFC3261_BRANCH_ID "z9hG4bK"
+#define PJSIP_RFC3261_BRANCH_LEN 7
+
+/* Transaction related constants. */
+
+/**
+ * Initial memory size for transaction layer. The bulk of pool usage
+ * for transaction layer will be used to create the hash table, so
+ * setting this value too high will not help too much with reducing
+ * fragmentation and the memory will most likely be wasted.
+ */
+#ifndef PJSIP_POOL_TSX_LAYER_LEN
+# define PJSIP_POOL_TSX_LAYER_LEN 512
+#endif
+
+/**
+ * Memory increment for transaction layer. The bulk of pool usage
+ * for transaction layer will be used to create the hash table, so
+ * setting this value too high will not help too much with reducing
+ * fragmentation and the memory will most likely be wasted.
+ */
+#ifndef PJSIP_POOL_TSX_LAYER_INC
+# define PJSIP_POOL_TSX_LAYER_INC 512
+#endif
+
+/**
+ * Initial memory size for a SIP transaction object.
+ */
+#ifndef PJSIP_POOL_TSX_LEN
+# define PJSIP_POOL_TSX_LEN 1536 /* 768 */
+#endif
+
+/**
+ * Memory increment for transaction object.
+ */
+#ifndef PJSIP_POOL_TSX_INC
+# define PJSIP_POOL_TSX_INC 256
+#endif
+
+/**
+ * Delay for non-100 1xx retransmission, in seconds.
+ * Set to 0 to disable this feature.
+ *
+ * Default: 60 seconds
+ */
+#ifndef PJSIP_TSX_1XX_RETRANS_DELAY
+# define PJSIP_TSX_1XX_RETRANS_DELAY 60
+#endif
+
+#define PJSIP_MAX_TSX_KEY_LEN (PJSIP_MAX_URL_SIZE*2)
+
+/* User agent. */
+#define PJSIP_POOL_LEN_USER_AGENT 1024
+#define PJSIP_POOL_INC_USER_AGENT 1024
+
+/* Message/URL related constants. */
+#define PJSIP_MAX_CALL_ID_LEN pj_GUID_STRING_LENGTH()
+#define PJSIP_MAX_TAG_LEN pj_GUID_STRING_LENGTH()
+#define PJSIP_MAX_BRANCH_LEN (PJSIP_RFC3261_BRANCH_LEN + pj_GUID_STRING_LENGTH() + 2)
+#define PJSIP_MAX_HNAME_LEN 64
+
+/* Dialog related constants. */
+#define PJSIP_POOL_LEN_DIALOG 1200
+#define PJSIP_POOL_INC_DIALOG 512
+
+/* Maximum header types. */
+#define PJSIP_MAX_HEADER_TYPES 72
+
+/* Maximum URI types. */
+#define PJSIP_MAX_URI_TYPES 4
+
+/*****************************************************************************
+ * Default timeout settings, in miliseconds.
+ */
+
+/** Transaction T1 timeout value. */
+#if !defined(PJSIP_T1_TIMEOUT)
+# define PJSIP_T1_TIMEOUT 500
+#endif
+
+/** Transaction T2 timeout value. */
+#if !defined(PJSIP_T2_TIMEOUT)
+# define PJSIP_T2_TIMEOUT 4000
+#endif
+
+/** Transaction completed timer for non-INVITE */
+#if !defined(PJSIP_T4_TIMEOUT)
+# define PJSIP_T4_TIMEOUT 5000
+#endif
+
+/** Transaction completed timer for INVITE */
+#if !defined(PJSIP_TD_TIMEOUT)
+# define PJSIP_TD_TIMEOUT 32000
+#endif
+
+
+/*****************************************************************************
+ * Authorization
+ */
+
+/**
+ * If this flag is set, the stack will keep the Authorization/Proxy-Authorization
+ * headers that are sent in a cache. Future requests with the same realm and
+ * the same method will use the headers in the cache (as long as no qop is
+ * required by server).
+ *
+ * Turning on this flag will make authorization process goes faster, but
+ * will grow the memory usage undefinitely until the dialog/registration
+ * session is terminated.
+ *
+ * Default: 0
+ */
+#if !defined(PJSIP_AUTH_HEADER_CACHING)
+# define PJSIP_AUTH_HEADER_CACHING 0
+#endif
+
+/**
+ * If this flag is set, the stack will proactively send Authorization/Proxy-
+ * Authorization header for next requests. If next request has the same method
+ * with any of previous requests, then the last header which is saved in
+ * the cache will be used (if PJSIP_AUTH_CACHING is set). Otherwise a fresh
+ * header will be recalculated. If a particular server has requested qop, then
+ * a fresh header will always be calculated.
+ *
+ * If this flag is NOT set, then the stack will only send Authorization/Proxy-
+ * Authorization headers when it receives 401/407 response from server.
+ *
+ * Turning ON this flag will grow memory usage of a dialog/registration pool
+ * indefinitely until it is terminated, because the stack needs to keep the
+ * last WWW-Authenticate/Proxy-Authenticate challenge.
+ *
+ * Default: 0
+ */
+#if !defined(PJSIP_AUTH_AUTO_SEND_NEXT)
+# define PJSIP_AUTH_AUTO_SEND_NEXT 0
+#endif
+
+/**
+ * Support qop="auth" directive.
+ * This option also requires client to cache the last challenge offered by
+ * server.
+ *
+ * Default: 1
+ */
+#if !defined(PJSIP_AUTH_QOP_SUPPORT)
+# define PJSIP_AUTH_QOP_SUPPORT 1
+#endif
+
+
+/**
+ * Maximum number of stale retries when server keeps rejecting our request
+ * with stale=true.
+ *
+ * Default: 3
+ */
+#ifndef PJSIP_MAX_STALE_COUNT
+# define PJSIP_MAX_STALE_COUNT 3
+#endif
+
+
+/**
+ * Specify support for IMS/3GPP digest AKA authentication version 1 and 2
+ * (AKAv1-MD5 and AKAv2-MD5 respectively).
+ *
+ * Default: 0 (for now)
+ */
+#ifndef PJSIP_HAS_DIGEST_AKA_AUTH
+# define PJSIP_HAS_DIGEST_AKA_AUTH 0
+#endif
+
+
+/**
+ * Specify the number of seconds to refresh the client registration
+ * before the registration expires.
+ *
+ * Default: 5 seconds
+ */
+#ifndef PJSIP_REGISTER_CLIENT_DELAY_BEFORE_REFRESH
+# define PJSIP_REGISTER_CLIENT_DELAY_BEFORE_REFRESH 5
+#endif
+
+
+/**
+ * Specify whether client registration should check for its registered
+ * contact in Contact header of successful REGISTE response to determine
+ * whether registration has been successful. This setting may be disabled
+ * if non-compliant registrar is unable to return correct Contact header.
+ *
+ * This setting can be changed in run-time by settting \a regc.check_contact
+ * field of pjsip_cfg().
+ *
+ * Default is 1
+ */
+#ifndef PJSIP_REGISTER_CLIENT_CHECK_CONTACT
+# define PJSIP_REGISTER_CLIENT_CHECK_CONTACT 1
+#endif
+
+
+/**
+ * Specify whether client registration should add "x-uid" extension
+ * parameter in all Contact URIs that it registers to assist the
+ * matching of Contact URIs in the 200/OK REGISTER response, in
+ * case the registrar is unable to return exact Contact URI in the
+ * 200/OK response.
+ *
+ * This setting can be changed in run-time by setting
+ * \a regc.add_xuid_param field of pjsip_cfg().
+ *
+ * Default is 0.
+ */
+#ifndef PJSIP_REGISTER_CLIENT_ADD_XUID_PARAM
+# define PJSIP_REGISTER_CLIENT_ADD_XUID_PARAM 0
+#endif
+
+
+/*****************************************************************************
+ * SIP Event framework and presence settings.
+ */
+
+/**
+ * Specify the time (in seconds) to send SUBSCRIBE to refresh client
+ * subscription before the actual interval expires.
+ *
+ * Default: 5 seconds
+ */
+#ifndef PJSIP_EVSUB_TIME_UAC_REFRESH
+# define PJSIP_EVSUB_TIME_UAC_REFRESH 5
+#endif
+
+
+/**
+ * Specify the time (in seconds) to send PUBLISH to refresh client
+ * publication before the actual interval expires.
+ *
+ * Default: 5 seconds
+ */
+#ifndef PJSIP_PUBLISHC_DELAY_BEFORE_REFRESH
+# define PJSIP_PUBLISHC_DELAY_BEFORE_REFRESH 5
+#endif
+
+
+/**
+ * Specify the time (in seconds) to wait for the final NOTIFY from the
+ * server after client has sent un-SUBSCRIBE request.
+ *
+ * Default: 5 seconds
+ */
+#ifndef PJSIP_EVSUB_TIME_UAC_TERMINATE
+# define PJSIP_EVSUB_TIME_UAC_TERMINATE 5
+#endif
+
+
+/**
+ * Specify the time (in seconds) for client subscription to wait for another
+ * NOTIFY from the server, if it has rejected the last NOTIFY with non-2xx
+ * final response (such as 401). If further NOTIFY is not received within
+ * this period, the client will unsubscribe.
+ *
+ * Default: 5 seconds
+ */
+#ifndef PJSIP_EVSUB_TIME_UAC_WAIT_NOTIFY
+# define PJSIP_EVSUB_TIME_UAC_WAIT_NOTIFY 5
+#endif
+
+
+/**
+ * Specify the default expiration time for presence event subscription, for
+ * both client and server subscription. For client subscription, application
+ * can override this by specifying positive non-zero value in "expires"
+ * parameter when calling #pjsip_pres_initiate(). For server subscription,
+ * we would take the expiration value from the Expires header sent by client
+ * in the SUBSCRIBE request if the header exists and its value is less than
+ * this setting, otherwise this setting will be used.
+ *
+ * Default: 600 seconds (10 minutes)
+ */
+#ifndef PJSIP_PRES_DEFAULT_EXPIRES
+# define PJSIP_PRES_DEFAULT_EXPIRES 600
+#endif
+
+
+/**
+ * Specify the status code value to respond to bad message body in NOTIFY
+ * request for presence. Scenarios that are considered bad include non-
+ * PIDF/XML and non-XPIDF/XML body, multipart message bodies without PIDF/XML
+ * nor XPIDF/XML part, and bad (parsing error) PIDF and X-PIDF bodies
+ * themselves.
+ *
+ * Default value is 488. Application may change this to 200 to ignore the
+ * unrecognised content (this is useful if the application wishes to handle
+ * the content itself). Only non-3xx final response code is allowed here.
+ *
+ * Default: 488 (Not Acceptable Here)
+ */
+#ifndef PJSIP_PRES_BAD_CONTENT_RESPONSE
+# define PJSIP_PRES_BAD_CONTENT_RESPONSE 488
+#endif
+
+
+/**
+ * Add "timestamp" information in generated PIDF document for both server
+ * subscription and presence publication.
+ *
+ * Default: 1 (yes)
+ */
+#ifndef PJSIP_PRES_PIDF_ADD_TIMESTAMP
+# define PJSIP_PRES_PIDF_ADD_TIMESTAMP 1
+#endif
+
+
+/**
+ * Default session interval for Session Timer (RFC 4028) extension, in
+ * seconds. As specified in RFC 4028 Section 4, this value must not be
+ * less than the absolute minimum for the Session-Expires header field
+ * 90 seconds, and the recommended value is 1800 seconds.
+ *
+ * Default: 1800 seconds
+ */
+#ifndef PJSIP_SESS_TIMER_DEF_SE
+# define PJSIP_SESS_TIMER_DEF_SE 1800
+#endif
+
+
+/**
+ * Specify whether the client publication session should queue the
+ * PUBLISH request should there be another PUBLISH transaction still
+ * pending. If this is set to false, the client will return error
+ * on the PUBLISH request if there is another PUBLISH transaction still
+ * in progress.
+ *
+ * Default: 1 (yes)
+ */
+#ifndef PJSIP_PUBLISHC_QUEUE_REQUEST
+# define PJSIP_PUBLISHC_QUEUE_REQUEST 1
+#endif
+
+
+/**
+ * Specify the default expiration time for Message Waiting Indication
+ * (RFC 3842) event subscription, for both client and server subscription.
+ * For client subscription, application can override this by specifying
+ * positive non-zero value in "expires" parameter when calling
+ * #pjsip_mwi_initiate(). For server subscription, we would take the
+ * expiration value from the Expires header sent by client in the SUBSCRIBE
+ * request if the header exists and its value is less than this setting,
+ * otherwise this setting will be used.
+ *
+ * Default: 3600 seconds
+ */
+#ifndef PJSIP_MWI_DEFAULT_EXPIRES
+# define PJSIP_MWI_DEFAULT_EXPIRES 3600
+#endif
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#include <pj/config.h>
+
+
+#endif /* __PJSIP_SIP_CONFIG_H__ */
+
diff --git a/pjsip/include/pjsip/sip_dialog.h b/pjsip/include/pjsip/sip_dialog.h
new file mode 100644
index 0000000..63e12ac
--- /dev/null
+++ b/pjsip/include/pjsip/sip_dialog.h
@@ -0,0 +1,791 @@
+/* $Id: sip_dialog.h 4173 2012-06-20 10:39:05Z ming $ */
+/*
+ * 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_DIALOG_H__
+#define __PJSIP_SIP_DIALOG_H__
+
+
+/**
+ * @file sip_dialog.h
+ * @brief SIP Dialog abstraction
+ */
+
+#include <pjsip/sip_msg.h>
+#include <pjsip/sip_auth.h>
+#include <pjsip/sip_errno.h>
+#include <pjsip/sip_transport.h>
+#include <pjsip/sip_util.h>
+#include <pj/sock.h>
+#include <pj/assert.h>
+
+
+/**
+ * @defgroup PJSIP_DIALOG Base Dialog
+ * @ingroup PJSIP_UA
+ * @brief The base dialog framework to support dialog usages.
+ * @{
+ *
+ * The base dialog framework provides management for base dialog
+ * properties such as <b>From</b> header, <b>To</b> header, <b>CSeq</b>
+ * sequencing, <b>Call-ID</b> header, <b>Contact</b> header management,
+ * dialog <b>route-set</b> management, and common <b>authentication</b>.
+ * This basic dialog functionality will be shared by all <b>dialog
+ * usages</b> of a particular dialog.
+ *
+ * More detailed information is explained in
+ * <A HREF="/docs.htm">PJSIP Developer's Guide</A>
+ * PDF document, and readers are encouraged to read the document to
+ * get the concept behind dialog, dialog usages, and INVITE sessions.
+ *
+ * Application MUST initialize the user agent layer module by calling
+ * #pjsip_ua_init_module() before using any of the dialog API, and link
+ * the application with with <b>pjsip-core</b> library.
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * This structure is used to describe dialog's participants, which in this
+ * case is local party (i.e. us) and remote party.
+ */
+typedef struct pjsip_dlg_party
+{
+ pjsip_fromto_hdr *info; /**< From/To header, inc tag. */
+ pj_str_t info_str; /**< String rep of info header. */
+ pj_uint32_t tag_hval; /**< Hashed value of the tag. */
+ pjsip_contact_hdr *contact; /**< Contact header. */
+ pj_int32_t first_cseq;/**< First CSeq seen. */
+ pj_int32_t cseq; /**< Next sequence number. */
+} pjsip_dlg_party;
+
+
+/**
+ * Dialog state.
+ */
+typedef enum pjsip_dialog_state
+{
+ /** Dialog is not established. */
+ PJSIP_DIALOG_STATE_NULL,
+
+ /** Dialog has been established (probably early) */
+ PJSIP_DIALOG_STATE_ESTABLISHED
+} pjsip_dialog_state;
+
+
+/**
+ * Dialog capability status.
+ */
+typedef enum pjsip_dialog_cap_status
+{
+ /** Capability is unsupported. */
+ PJSIP_DIALOG_CAP_UNSUPPORTED = 0,
+
+ /** Capability is supported */
+ PJSIP_DIALOG_CAP_SUPPORTED = 1,
+
+ /**
+ * Unknown capability status. This is usually because we lack the
+ * capability info which is retrieved from capability header specified
+ * in the dialog messages.
+ */
+ PJSIP_DIALOG_CAP_UNKNOWN = 2
+} pjsip_dialog_cap_status;
+
+
+/**
+ * This structure describes the dialog structure. Application MUST NOT
+ * try to SET the values here directly, but instead it MUST use the
+ * appropriate dialog API. The dialog declaration only needs to be made
+ * visible because other PJSIP modules need to see it (e.g. INVITE session,
+ * the event framework, etc.).
+ *
+ * Application MAY READ the dialog contents directly after it acquires
+ * dialog lock.
+ *
+ * To acquire dialog lock, use #pjsip_dlg_inc_lock(), and to release it,
+ * use #pjsip_dlg_dec_lock(). DO NOT USE pj_mutex_lock()/pj_mutex_unlock()
+ * on the dialog's mutex directly, because this will not protect against
+ * dialog being destroyed.
+ */
+struct pjsip_dialog
+{
+ /** The dialog set list. */
+ PJ_DECL_LIST_MEMBER(pjsip_dialog);
+
+ /* Dialog's system properties. */
+ char obj_name[PJ_MAX_OBJ_NAME]; /**< Standard id. */
+ pj_pool_t *pool; /**< Dialog's pool. */
+ pj_mutex_t *mutex_; /**< Dialog's mutex. Do not call!!
+ Use pjsip_dlg_inc_lock() instead! */
+ pjsip_user_agent *ua; /**< User agent instance. */
+ pjsip_endpoint *endpt; /**< Endpoint instance. */
+
+ /** The dialog set which this dialog belongs (opaque type). */
+ void *dlg_set;
+
+ /* Dialog's session properties. */
+ pjsip_dialog_state state; /**< Dialog state. */
+ pjsip_uri *target; /**< Current target. */
+ pjsip_target_set target_set; /**< Target set, for UAC only. */
+ pjsip_hdr inv_hdr; /**< Headers from hparam in dest URL */
+ pjsip_dlg_party local; /**< Local party info. */
+ pjsip_dlg_party remote; /**< Remote party info. */
+ pjsip_hdr rem_cap_hdr;/**< List of remote capability header. */
+ pjsip_role_e role; /**< Initial role. */
+ pj_bool_t uac_has_2xx;/**< UAC has received 2xx response? */
+ pj_bool_t secure; /**< Use secure transport? */
+ pj_bool_t add_allow; /**< Add Allow header in requests? */
+ pjsip_cid_hdr *call_id; /**< Call-ID header. */
+ pjsip_route_hdr route_set; /**< Route set. */
+ pj_bool_t route_set_frozen; /**< Route set has been set. */
+ pjsip_auth_clt_sess auth_sess; /**< Client authentication session. */
+
+ /** Session counter. */
+ int sess_count; /**< Number of sessions. */
+
+ /** Transaction counter. */
+ int tsx_count; /**< Number of pending transactions. */
+
+ /** Transport selector. */
+ pjsip_tpselector tp_sel;
+
+ /* Dialog usages. */
+ unsigned usage_cnt; /**< Number of registered usages. */
+ pjsip_module *usage[PJSIP_MAX_MODULE]; /**< Array of usages,
+ priority sorted */
+
+ /** Module specific data. */
+ void *mod_data[PJSIP_MAX_MODULE]; /**< Module data. */
+
+ /**
+ * 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. */
+};
+
+
+/**
+ * This utility function returns PJ_TRUE if the specified method is a
+ * dialog creating request. This method property is used to determine
+ * whether Contact header should be included in outgoing request.
+ *
+ * @param m The SIP method.
+ *
+ * @return PJ_TRUE if the method creates a dialog.
+ */
+PJ_DECL(pj_bool_t) pjsip_method_creates_dialog(const pjsip_method *m);
+
+/**
+ * Create a new dialog and return the instance in p_dlg parameter.
+ * After creating the dialog, application can add modules as dialog usages
+ * by calling #pjsip_dlg_add_usage().
+ *
+ * If the request has To tag parameter, dialog's local tag will be initialized
+ * from this value. Otherwise a globally unique id generator will be invoked to
+ * create dialog's local tag.
+ *
+ * This function also initializes the dialog's route set based on the
+ * Record-Route headers in the request, if present.
+ *
+ * Note that initially, the session count in the dialog will be initialized
+ * to zero.
+ *
+ * @param ua The user agent module instance.
+ * @param local_uri Dialog local URI (i.e. From header).
+ * @param local_contact Optional dialog local Contact to be put as Contact
+ * header value, hence the format must follow
+ * RFC 3261 Section 20.10:
+ * When the header field value contains a display
+ * name, the URI including all URI parameters is
+ * enclosed in "<" and ">". If no "<" and ">" are
+ * present, all parameters after the URI are header
+ * parameters, not URI parameters. The display name
+ * can be tokens, or a quoted string, if a larger
+ * character set is desired.
+ * If this argument is NULL, the Contact will be taken
+ * from the local URI.
+ * @param remote_uri Dialog remote URI (i.e. To header).
+ * @param target Optional initial remote target. If this argument
+ * is NULL, the initial target will be set to
+ * remote URI.
+ * @param p_dlg Pointer to receive the dialog.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_create_uac( pjsip_user_agent *ua,
+ const pj_str_t *local_uri,
+ const pj_str_t *local_contact,
+ const pj_str_t *remote_uri,
+ const pj_str_t *target,
+ pjsip_dialog **p_dlg);
+
+
+/**
+ * Initialize UAS dialog from the information found in the incoming request
+ * that creates a dialog (such as INVITE, REFER, or SUBSCRIBE), and set the
+ * local Contact to contact. If contact is not specified, the local contact
+ * is initialized from the URI in the To header in the request.
+ *
+ * This function will also create UAS transaction for the incoming request,
+ * and associate the transaction to the rdata. Application can query the
+ * transaction used to handle this request by calling #pjsip_rdata_get_tsx()
+ * after this function returns.
+ *
+ * Note that initially, the session count in the dialog will be initialized
+ * to zero.
+ *
+ *
+ * @param ua The user agent module instance.
+ * @param rdata The incoming request that creates the dialog,
+ * such as INVITE, SUBSCRIBE, or REFER.
+ * @param contact Optional dialog local Contact to be put as Contact
+ * header value, hence the format must follow
+ * RFC 3261 Section 20.10:
+ * When the header field value contains a display
+ * name, the URI including all URI parameters is
+ * enclosed in "<" and ">". If no "<" and ">" are
+ * present, all parameters after the URI are header
+ * parameters, not URI parameters. The display name
+ * can be tokens, or a quoted string, if a larger
+ * character set is desired.
+ * If this argument is NULL, the local contact will be
+ * initialized from the value of To header in the
+ * request.
+ * @param p_dlg Pointer to receive the dialog.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_create_uas( pjsip_user_agent *ua,
+ pjsip_rx_data *rdata,
+ const pj_str_t *contact,
+ pjsip_dialog **p_dlg);
+
+
+/**
+ * Lock/bind dialog to a specific transport/listener. This is optional,
+ * as normally transport will be selected automatically based on the
+ * destination of messages upon resolver completion. When the dialog is
+ * explicitly bound to the specific transport/listener, all transactions
+ * originated by this dialog will use the specified transport/listener
+ * when sending outgoing requests.
+ *
+ * Note that this doesn't affect the Contact header generated by this
+ * dialog. Application must manually update the Contact header if
+ * necessary, to adjust the address according to the transport being
+ * selected.
+ *
+ * @param dlg The dialog instance.
+ * @param sel Transport selector containing the specification of
+ * transport or listener to be used by this dialog
+ * to send requests.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_set_transport(pjsip_dialog *dlg,
+ const pjsip_tpselector *sel);
+
+
+/**
+ * Set the "sent-by" field of the Via header for outgoing requests.
+ *
+ * @param dlg The dialog instance.
+ * @param via_addr Set via_addr to use for the Via header or NULL to use
+ * the transport's published name.
+ * @param via_tp via_addr will only be used if we are using via_tp
+ * transport.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_set_via_sent_by(pjsip_dialog *dlg,
+ pjsip_host_port *via_addr,
+ pjsip_transport *via_tp);
+
+
+/**
+ * Create a new (forked) dialog on receipt on forked response in rdata.
+ * The new dialog will be created from original_dlg, except that it will have
+ * new remote tag as copied from the To header in the response. Upon return,
+ * the new_dlg will have been registered to the user agent. Applications just
+ * need to add modules as dialog's usages.
+ *
+ * Note that initially, the session count in the dialog will be initialized
+ * to zero.
+ *
+ * @param original_dlg The original UAC dialog.
+ * @param rdata The incoming forked response message.
+ * @param new_dlg Pointer to receive the new dialog.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_fork(const pjsip_dialog *original_dlg,
+ const pjsip_rx_data *rdata,
+ pjsip_dialog **new_dlg );
+
+/**
+ * Forcefully terminate the dialog. Application can only call this function
+ * when there is no session associated to the dialog. If there are sessions
+ * that use this dialog, this function will refuse to terminate the dialog.
+ * For this case, application MUST call the appropriate termination function
+ * for each dialog session (e.g. #pjsip_inv_terminate() to terminate INVITE
+ * session).
+ *
+ * @param dlg The dialog.
+ *
+ * @return PJ_SUCCESS if dialog has been terminated.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_terminate( pjsip_dialog *dlg );
+
+
+/**
+ * Set dialog's initial route set to route_set list. This can only be called
+ * for UAC dialog, before any request is sent. After dialog has been
+ * established, the route set can not be changed.
+ *
+ * For UAS dialog,the route set will be initialized in pjsip_dlg_create_uas()
+ * from the Record-Route headers in the incoming request.
+ *
+ * The route_set argument is standard list of Route headers (i.e. with
+ * sentinel).
+ *
+ * @param dlg The UAC dialog.
+ * @param route_set List of Route header.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_set_route_set( pjsip_dialog *dlg,
+ const pjsip_route_hdr *route_set );
+
+/**
+ * Increment the number of sessions in the dialog. Note that initially
+ * (after created) the dialog has the session counter set to zero.
+ *
+ * @param dlg The dialog.
+ * @param mod The module that increments the session counter.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_inc_session( pjsip_dialog *dlg,
+ pjsip_module *mod);
+
+
+/**
+ * Decrement the number of sessions in the dialog. Once the session counter
+ * reach zero and there is no pending transaction, the dialog will be
+ * destroyed. Note that this function may destroy the dialog immediately
+ * if there is no pending transaction when this function is called.
+ *
+ * @param dlg The dialog.
+ * @param mod The module that decrements the session counter.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_dec_session( pjsip_dialog *dlg,
+ pjsip_module *mod);
+
+/**
+ * Add a module as dialog usage, and optionally set the module specific data.
+ *
+ * @param dlg The dialog.
+ * @param module The module to be registered as dialog usage.
+ * @param mod_data Optional arbitrary data to be attached to dialog's
+ * mod_data array at the module's index.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_add_usage( pjsip_dialog *dlg,
+ pjsip_module *module,
+ void *mod_data );
+
+/**
+ * Check if the specified module has been registered as usage to the dialog.
+ *
+ * @param dlg The dialog.
+ * @param module The module.
+ *
+ * @return PJ_TRUE if the specified module is currently
+ * registered as a usage to the dialog.
+ */
+PJ_DECL(pj_bool_t) pjsip_dlg_has_usage(pjsip_dialog *dlg,
+ pjsip_module *module);
+
+/**
+ * Attach module specific data to the dialog. Application can also set
+ * the value directly by accessing dlg->mod_data[module_id].
+ *
+ * @param dlg The dialog
+ * @param mod_id The ID of the module from which the data is to be
+ * set to the dialog.
+ * @param data Arbitrary data.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_set_mod_data( pjsip_dialog *dlg,
+ int mod_id,
+ void *data );
+
+/**
+ * Get module specific data previously attached to the dialog. Application
+ * can also get value directly by accessing dlg->mod_data[module_id].
+ *
+ * @param dlg The dialog
+ * @param mod_id The ID of the module from which the data is to be
+ * retrieved from the dialog.
+ *
+ * @return The data that was previously set, or NULL.
+ */
+PJ_DECL(void*) pjsip_dlg_get_mod_data( pjsip_dialog *dlg,
+ int mod_id);
+
+
+/**
+ * Lock dialog and increment session counter termporarily, to prevent it
+ * from being destroyed.
+ *
+ * @param dlg The dialog.
+ */
+PJ_DECL(void) pjsip_dlg_inc_lock( pjsip_dialog *dlg );
+
+/**
+ * Try to acquire dialog's lock, but return immediately if lock can not
+ * be acquired.
+ *
+ * @param dlg The dialog.
+ *
+ * @return PJ_SUCCESS if lock has been acquired.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_try_inc_lock( pjsip_dialog *dlg );
+
+/**
+ * Unlock dialog and decrement temporary session counter. After this function
+ * is called, dialog may be destroyed.
+ *
+ * @param dlg The dialog.
+ */
+PJ_DECL(void) pjsip_dlg_dec_lock( pjsip_dialog *dlg );
+
+
+/**
+ * Get the dialog instance in the incoming rdata. If an incoming message
+ * matches an existing dialog, the user agent must have put the matching
+ * dialog instance in the rdata, or otherwise this function will return
+ * NULL if the message didn't match any existing dialog.
+ *
+ * This function can only be called after endpoint distributes the message
+ * to the transaction layer or UA layer. In other words, application can
+ * only call this function in the context of module that runs in priority
+ * number higher than PJSIP_MOD_PRIORITY_UA_PROXY_LAYER.
+ *
+ * @param rdata Incoming message buffer.
+ *
+ * @return The dialog instance that "owns" the message.
+ */
+PJ_DECL(pjsip_dialog*) pjsip_rdata_get_dlg( pjsip_rx_data *rdata );
+
+/**
+ * Get the associated dialog for the specified transaction, if any.
+ *
+ * @param tsx The transaction.
+ *
+ * @return The dialog instance which has been registered
+ * to the transaction as transaction user, or
+ * NULL if the transaction is outside any dialogs.
+ */
+PJ_DECL(pjsip_dialog*) pjsip_tsx_get_dlg( pjsip_transaction *tsx );
+
+
+/**
+ * Create a basic/generic request with the specified method and optionally
+ * specify the cseq. Use value -1 for cseq to have the dialog automatically
+ * put next cseq number for the request. Otherwise for some requests,
+ * e.q. CANCEL and ACK, application must put the CSeq in the original
+ * INVITE request as the parameter.
+ *
+ * This function will also put Contact header where appropriate.
+ *
+ * @param dlg The dialog instance.
+ * @param method The method of the request.
+ * @param cseq Optional CSeq, which only needs to be specified
+ * when creating ACK and CANCEL. For other requests,
+ * specify -1 to use dialog's internal counter.
+ * @param tdata Pointer to receive the request's transmit
+ * data buffer.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_create_request( pjsip_dialog *dlg,
+ const pjsip_method *method,
+ int cseq,
+ pjsip_tx_data **tdata);
+
+
+/**
+ * Send request message to remote peer. If the request is not an ACK request,
+ * the dialog will send the request statefully, by creating an UAC transaction
+ * and send the request with the transaction.
+ *
+ * Also when the request is not ACK or CANCEL, the dialog will increment its
+ * local cseq number and update the cseq in the request according to dialog's
+ * cseq.
+ *
+ * If p_tsx is not null, this argument will be set with the transaction
+ * instance that was used to send the request.
+ *
+ * This function will decrement the transmit data's reference counter
+ * regardless the status of the operation.
+ *
+ * @param dlg The dialog.
+ * @param tdata The request message to be sent.
+ * @param mod_data_id Optional module data index to put an optional data
+ * into the transaction. If no module data is to be
+ * attached, this value should be -1.
+ * @param mod_data Optional module data to be attached to the
+ * transaction at mod_data_id index.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_send_request ( pjsip_dialog *dlg,
+ pjsip_tx_data *tdata,
+ int mod_data_id,
+ void *mod_data);
+
+
+/**
+ * Create a response message for the incoming request in rdata with status
+ * code st_code and optional status text st_text. This function is different
+ * than endpoint's API #pjsip_endpt_create_response() in that the dialog
+ * function adds Contact header and Record-Routes headers in the response
+ * where appropriate.
+ *
+ * @param dlg The dialog.
+ * @param rdata The incoming request message for which the
+ * response will be created.
+ * @param st_code Status code.
+ * @param st_text Optional string for custom status reason text.
+ * @param tdata Pointer to receive the response message transmit
+ * data buffer.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_create_response( pjsip_dialog *dlg,
+ pjsip_rx_data *rdata,
+ int st_code,
+ const pj_str_t *st_text,
+ pjsip_tx_data **tdata);
+
+
+/**
+ * Modify previously sent response with other status code. Contact header
+ * will be added when appropriate.
+ *
+ * @param dlg The dialog.
+ * @param tdata The transmit data buffer containing response
+ * message to be modified.
+ * @param st_code New status code to be set.
+ * @param st_text Optional string for custom status reason text.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_modify_response( pjsip_dialog *dlg,
+ pjsip_tx_data *tdata,
+ int st_code,
+ const pj_str_t *st_text);
+
+
+/**
+ * Send response message statefully. The transaction instance MUST be the
+ * transaction that was reported on on_rx_request() callback.
+ *
+ * This function decrements the transmit data's reference counter regardless
+ * the status of the operation.
+ *
+ * @param dlg The dialog.
+ * @param tsx The UAS transaction associated with the incoming
+ * request. If the request is within a dialog, or
+ * a dialog has been created for the request that
+ * creates the dialog, application can get the
+ * transaction instance for the request by calling
+ * #pjsip_rdata_get_tsx().
+ * @param tdata Response message to be sent.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_send_response( pjsip_dialog *dlg,
+ pjsip_transaction *tsx,
+ pjsip_tx_data *tdata);
+
+
+/**
+ * This composite function sends response message statefully to an incoming
+ * request message inside dialog.
+ *
+ * @param dlg The endpoint instance.
+ * @param rdata The incoming request message.
+ * @param st_code Status code of the response.
+ * @param st_text Optional status text of the response.
+ * @param hdr_list Optional header list to be added to the response.
+ * @param body Optional message body to be added to the response.
+ *
+ * @return PJ_SUCCESS if response message has successfully been
+ * sent.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_respond( pjsip_dialog *dlg,
+ pjsip_rx_data *rdata,
+ int st_code,
+ const pj_str_t *st_text,
+ const pjsip_hdr *hdr_list,
+ const pjsip_msg_body *body );
+
+
+/**
+ * Check if remote peer have the specified capability as published
+ * in the dialog messages from remote peer.
+ *
+ * Notes:
+ * - The capability \a token lookup will apply exact match, but not
+ * case-sensitive, for example: <tt>"text/html"</tt> will not match
+ * <tt>"text / html"</tt> (notice the spaces).
+ *
+ * @param dlg The dialog.
+ * @param htype The header type to be checked, which value may be:
+ * - PJSIP_H_ACCEPT
+ * - PJSIP_H_ALLOW
+ * - PJSIP_H_SUPPORTED
+ * @param hname If htype specifies PJSIP_H_OTHER, then the header name
+ * must be supplied in this argument. Otherwise the value
+ * must be set to NULL.
+ * @param token The capability token to check. For example, if \a htype
+ * is PJSIP_H_ALLOW, then \a token specifies the method
+ * names; if \a htype is PJSIP_H_SUPPORTED, then \a token
+ * specifies the extension names such as "100rel".
+ *
+ * @return PJSIP_DIALOG_CAP_SUPPORTED if the specified capability
+ * is explicitly supported, see @pjsip_dialog_cap_status
+ * for more info.
+ */
+PJ_DECL(pjsip_dialog_cap_status) pjsip_dlg_remote_has_cap(
+ pjsip_dialog *dlg,
+ int htype,
+ const pj_str_t *hname,
+ const pj_str_t *token);
+
+/**
+ * Get the specified capability header from the remote capability headers
+ * stored in the dialog.
+ *
+ * @param dlg The dialog.
+ * @param htype The header type to be retrieved, which value may be:
+ * - PJSIP_H_ACCEPT
+ * - PJSIP_H_ALLOW
+ * - PJSIP_H_SUPPORTED
+ * @param hname If htype specifies PJSIP_H_OTHER, then the header name
+ * must be supplied in this argument. Otherwise the value
+ * must be set to NULL.
+ *
+ * @return The appropriate header, or NULL if the header is not
+ * available.
+ */
+PJ_DECL(const pjsip_hdr*) pjsip_dlg_get_remote_cap_hdr(pjsip_dialog *dlg,
+ int htype,
+ const pj_str_t *hname);
+
+/**
+ * Set remote capability from a SIP header containing array of capability
+ * tags/values.
+ *
+ * @param dlg The dialog.
+ * @param cap_hdr The SIP header.
+ *
+ * @return PJ_SUCCESS when successful, otherwise the appropriate
+ * error code will be returned.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_set_remote_cap_hdr(
+ pjsip_dialog *dlg,
+ const pjsip_generic_array_hdr *cap_hdr);
+
+/**
+ * Remove a remote capability header.
+ *
+ * @param dlg The dialog.
+ * @param htype The header type to be removed, which value may be:
+ * - PJSIP_H_ACCEPT
+ * - PJSIP_H_ALLOW
+ * - PJSIP_H_SUPPORTED
+ * @param hname If htype specifies PJSIP_H_OTHER, then the header name
+ * must be supplied in this argument. Otherwise the value
+ * must be set to NULL.
+ *
+ * @return PJ_SUCCESS when successful, otherwise the appropriate
+ * error code will be returned.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_remove_remote_cap_hdr(pjsip_dialog *dlg,
+ int htype,
+ const pj_str_t *hname);
+
+/**
+ * Update remote capabilities from a received message. The header types
+ * to be updated from the message will only be \a PJSIP_H_ACCEPT,
+ * \a PJSIP_H_ALLOW, and \a PJSIP_H_SUPPORTED.
+ *
+ * @param dlg The dialog.
+ * @param msg The received message.
+ * @param strict If this is set to PJ_TRUE, any header types missing
+ * from the message will cause removal of existing
+ * header types in the capability list. Otherwise, the
+ * capability list will not be modified when any header
+ * type is missing.
+ *
+ * @return PJ_SUCCESS when successful, otherwise the appropriate
+ * error code will be returned.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_update_remote_cap(pjsip_dialog *dlg,
+ const pjsip_msg *msg,
+ pj_bool_t strict);
+
+
+
+/**
+ * @}
+ */
+
+/*
+ * Internal (called by sip_ua_layer.c)
+ */
+
+/* Receives transaction event (called by user_agent module) */
+void pjsip_dlg_on_tsx_state( pjsip_dialog *dlg,
+ pjsip_transaction *tsx,
+ pjsip_event *e );
+
+void pjsip_dlg_on_rx_request( pjsip_dialog *dlg,
+ pjsip_rx_data *rdata );
+
+void pjsip_dlg_on_rx_response( pjsip_dialog *dlg,
+ pjsip_rx_data *rdata );
+
+
+
+PJ_END_DECL
+
+
+#endif /* __PJSIP_SIP_DIALOG_H__ */
+
diff --git a/pjsip/include/pjsip/sip_endpoint.h b/pjsip/include/pjsip/sip_endpoint.h
new file mode 100644
index 0000000..ac3f525
--- /dev/null
+++ b/pjsip/include/pjsip/sip_endpoint.h
@@ -0,0 +1,584 @@
+/* $Id: sip_endpoint.h 4154 2012-06-05 10:41:17Z bennylp $ */
+/*
+ * 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_ENDPOINT_H__
+#define __PJSIP_SIP_ENDPOINT_H__
+
+/**
+ * @file sip_endpoint.h
+ * @brief SIP Endpoint.
+ */
+
+#include <pjsip/sip_transport.h>
+#include <pjsip/sip_resolve.h>
+
+/**
+ * @defgroup PJSIP_CORE_CORE At the Very Core
+ * @ingroup PJSIP_CORE
+ * @brief The very core of PJSIP.
+ */
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJSIP_ENDPT Endpoint
+ * @ingroup PJSIP_CORE_CORE
+ * @brief The master, owner of all objects
+ *
+ * SIP Endpoint instance (pjsip_endpoint) can be viewed as the master/owner of
+ * all SIP objects in an application. It performs the following roles:
+ * - it manages the allocation/deallocation of memory pools for all objects.
+ * - it manages listeners and transports, and how they are used by
+ * transactions.
+ * - it receives incoming messages from transport layer and automatically
+ * dispatches them to the correct transaction (or create a new one).
+ * - it has a single instance of timer management (timer heap).
+ * - it manages modules, which is the primary means of extending the library.
+ * - it provides single polling function for all objects and distributes
+ * events.
+ * - it automatically handles incoming requests which can not be handled by
+ * existing modules (such as when incoming request has unsupported method).
+ * - and so on..
+ *
+ * Application should only instantiate one SIP endpoint instance for every
+ * process.
+ *
+ * @{
+ */
+
+
+/**
+ * Type of callback to register to pjsip_endpt_atexit().
+ */
+typedef void (*pjsip_endpt_exit_callback)(pjsip_endpoint *endpt);
+
+
+/**
+ * Create an instance of SIP endpoint from the specified pool factory.
+ * The pool factory reference then will be kept by the endpoint, so that
+ * future memory allocations by SIP components will be taken from the same
+ * pool factory.
+ *
+ * @param pf Pool factory that will be used for the lifetime of
+ * endpoint.
+ * @param name Optional name to be specified for the endpoint.
+ * If this parameter is NULL, then the name will use
+ * local host name.
+ * @param endpt Pointer to receive endpoint instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_endpt_create(pj_pool_factory *pf,
+ const char *name,
+ pjsip_endpoint **endpt);
+
+/**
+ * Destroy endpoint instance. Application must make sure that all pending
+ * transactions have been terminated properly, because this function does not
+ * check for the presence of pending transactions.
+ *
+ * @param endpt The SIP endpoint to be destroyed.
+ */
+PJ_DECL(void) pjsip_endpt_destroy(pjsip_endpoint *endpt);
+
+/**
+ * Get endpoint name.
+ *
+ * @param endpt The SIP endpoint instance.
+ *
+ * @return Endpoint name, as was registered during endpoint
+ * creation. The string is NULL terminated.
+ */
+PJ_DECL(const pj_str_t*) pjsip_endpt_name(const pjsip_endpoint *endpt);
+
+/**
+ * Poll for events. Application must call this function periodically to ensure
+ * that all events from both transports and timer heap are handled in timely
+ * manner. This function, like all other endpoint functions, is thread safe,
+ * and application may have more than one thread concurrently calling this function.
+ *
+ * @param endpt The endpoint.
+ * @param max_timeout Maximum time to wait for events, or NULL to wait forever
+ * until event is received.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_endpt_handle_events( pjsip_endpoint *endpt,
+ const pj_time_val *max_timeout);
+
+
+/**
+ * Handle events with additional info about number of events that
+ * have been handled.
+ *
+ * @param endpt The endpoint.
+ * @param max_timeout Maximum time to wait for events, or NULL to wait forever
+ * until event is received.
+ * @param count Optional argument to receive the number of events that
+ * have been handled by the function.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_endpt_handle_events2(pjsip_endpoint *endpt,
+ const pj_time_val *max_timeout,
+ unsigned *count);
+/**
+ * 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.
+ */
+#if PJ_TIMER_DEBUG
+#define pjsip_endpt_schedule_timer(ept,ent,d) \
+ pjsip_endpt_schedule_timer_dbg(ept, ent, d, \
+ __FILE__, __LINE__)
+
+PJ_DECL(pj_status_t) pjsip_endpt_schedule_timer_dbg(pjsip_endpoint *endpt,
+ pj_timer_entry *entry,
+ const pj_time_val *delay,
+ const char *src_file,
+ int src_line);
+#else
+PJ_DECL(pj_status_t) pjsip_endpt_schedule_timer( pjsip_endpoint *endpt,
+ pj_timer_entry *entry,
+ const pj_time_val *delay );
+#endif
+
+/**
+ * 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 );
+
+/**
+ * Get the timer heap instance of the SIP endpoint.
+ *
+ * @param endpt The endpoint.
+ *
+ * @return The timer heap instance.
+ */
+PJ_DECL(pj_timer_heap_t*) pjsip_endpt_get_timer_heap(pjsip_endpoint *endpt);
+
+
+/**
+ * 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
+ * allocated from the same pool factory. This function, like all other endpoint
+ * functions, is thread safe.
+ *
+ * @param endpt The SIP endpoint.
+ * @param pool_name Name to be assigned to the pool.
+ * @param initial The initial size of the pool.
+ * @param increment The resize size.
+ * @return Memory pool, or NULL on failure.
+ *
+ * @see pj_pool_create
+ */
+PJ_DECL(pj_pool_t*) pjsip_endpt_create_pool( pjsip_endpoint *endpt,
+ const char *pool_name,
+ pj_size_t initial,
+ pj_size_t increment );
+
+/**
+ * Return back pool to endpoint to be released back to the pool factory.
+ * This function, like all other endpoint functions, is thread safe.
+ *
+ * @param endpt The endpoint.
+ * @param pool The pool to be destroyed.
+ */
+PJ_DECL(void) pjsip_endpt_release_pool( pjsip_endpoint *endpt,
+ pj_pool_t *pool );
+
+/**
+ * Find transaction in endpoint's transaction table by the transaction's key.
+ * This function normally is only used by modules. The key for a transaction
+ * can be created by calling #pjsip_tsx_create_key.
+ *
+ * @param endpt The endpoint instance.
+ * @param key Transaction key, as created with #pjsip_tsx_create_key.
+ *
+ * @return The transaction, or NULL if it's not found.
+ */
+PJ_DECL(pjsip_transaction*) pjsip_endpt_find_tsx( pjsip_endpoint *endpt,
+ const pj_str_t *key );
+
+/**
+ * Register the transaction to the endpoint's transaction table.
+ * This function should only be used internally by the stack.
+ *
+ * @param endpt The SIP endpoint.
+ * @param tsx The transaction.
+ */
+PJ_DECL(void) pjsip_endpt_register_tsx( pjsip_endpoint *endpt,
+ pjsip_transaction *tsx);
+
+/**
+ * Forcefull destroy the transaction. This function should only be used
+ * internally by the stack.
+ *
+ * @param endpt The endpoint.
+ * @param tsx The transaction to destroy.
+ */
+PJ_DECL(void) pjsip_endpt_destroy_tsx( pjsip_endpoint *endpt,
+ pjsip_transaction *tsx);
+
+/**
+ * Create a new transmit data buffer.
+ * This function, like all other endpoint functions, is thread safe.
+ *
+ * @param endpt The endpoint.
+ * @param p_tdata Pointer to receive transmit data buffer.
+ *
+ * @return PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_endpt_create_tdata( pjsip_endpoint *endpt,
+ pjsip_tx_data **p_tdata);
+
+/**
+ * Create the DNS resolver instance. Application creates the DNS
+ * resolver instance, set the nameserver to be used by the DNS
+ * resolver, then set the DNS resolver to be used by the endpoint
+ * by calling #pjsip_endpt_set_resolver().
+ *
+ * @param endpt The SIP endpoint instance.
+ * @param p_resv Pointer to receive the DNS resolver instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t) pjsip_endpt_create_resolver(pjsip_endpoint *endpt,
+ pj_dns_resolver **p_resv);
+
+/**
+ * Set DNS resolver to be used by the SIP resolver. Application can set
+ * the resolver instance to NULL to disable DNS resolution (perhaps
+ * temporarily). When DNS resolver is disabled, the endpoint will resolve
+ * hostnames with the normal pj_gethostbyname() function.
+ *
+ * @param endpt The SIP endpoint instance.
+ * @param resv The resolver instance to be used by the SIP
+ * endpoint.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t) pjsip_endpt_set_resolver(pjsip_endpoint *endpt,
+ pj_dns_resolver *resv);
+
+/**
+ * Get the DNS resolver being used by the SIP resolver.
+ *
+ * @param endpt The SIP endpoint instance.
+ *
+ * @return The DNS resolver instance currently being used
+ * by the SIP endpoint.
+ */
+PJ_DECL(pj_dns_resolver*) pjsip_endpt_get_resolver(pjsip_endpoint *endpt);
+
+/**
+ * Asynchronously resolve a SIP target host or domain according to rule
+ * specified in RFC 3263 (Locating SIP Servers). When the resolving operation
+ * has completed, the callback will be called.
+ *
+ * @param endpt The endpoint instance.
+ * @param pool The pool to allocate resolver job.
+ * @param target The target specification to be resolved.
+ * @param token A user defined token to be passed back to callback function.
+ * @param cb The callback function.
+ */
+PJ_DECL(void) pjsip_endpt_resolve( pjsip_endpoint *endpt,
+ pj_pool_t *pool,
+ pjsip_host_info *target,
+ void *token,
+ pjsip_resolver_callback *cb);
+
+/**
+ * Get transport manager instance.
+ *
+ * @param endpt The endpoint.
+ *
+ * @return Transport manager instance.
+ */
+PJ_DECL(pjsip_tpmgr*) pjsip_endpt_get_tpmgr(pjsip_endpoint *endpt);
+
+/**
+ * Get ioqueue instance.
+ *
+ * @param endpt The endpoint.
+ *
+ * @return The ioqueue.
+ */
+PJ_DECL(pj_ioqueue_t*) pjsip_endpt_get_ioqueue(pjsip_endpoint *endpt);
+
+/**
+ * Find a SIP transport suitable for sending SIP message to the specified
+ * address. If transport selector ("sel") is set, then the function will
+ * check if the transport selected is suitable to send requests to the
+ * specified address.
+ *
+ * @see pjsip_tpmgr_acquire_transport
+ *
+ * @param endpt The SIP endpoint 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 p_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_endpt_acquire_transport( pjsip_endpoint *endpt,
+ pjsip_transport_type_e type,
+ const pj_sockaddr_t *remote,
+ int addr_len,
+ const pjsip_tpselector *sel,
+ pjsip_transport **p_tp);
+
+
+/**
+ * Find a SIP transport suitable for sending SIP message to the specified
+ * address by also considering the outgoing SIP message data. If transport
+ * selector ("sel") is set, then the function will check if the transport
+ * selected is suitable to send requests to the specified address.
+ *
+ * @see pjsip_tpmgr_acquire_transport
+ *
+ * @param endpt The SIP endpoint 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 SIP message data to be sent.
+ * @param p_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_endpt_acquire_transport2(pjsip_endpoint *endpt,
+ pjsip_transport_type_e type,
+ const pj_sockaddr_t *remote,
+ int addr_len,
+ const pjsip_tpselector *sel,
+ pjsip_tx_data *tdata,
+ pjsip_transport **p_tp);
+
+
+/*****************************************************************************
+ *
+ * Capabilities Management
+ *
+ * Modules may implement new capabilities to the stack. These capabilities
+ * are indicated by the appropriate SIP header fields, such as Accept,
+ * Accept-Encoding, Accept-Language, Allow, Supported, etc.
+ *
+ * When a module provides new capabilities to the stack, it registers these
+ * capabilities to the endpoint by supplying new tags (strings) to the
+ * appropriate header fields. Application (or other modules) can then query
+ * these header fields to get the list of supported capabilities, and may
+ * include these headers in the outgoing message.
+ *****************************************************************************
+ */
+
+/**
+ * Get the value of the specified capability header field.
+ *
+ * @param endpt The endpoint.
+ * @param htype The header type to be retrieved, which value may be:
+ * - PJSIP_H_ACCEPT
+ * - PJSIP_H_ALLOW
+ * - PJSIP_H_SUPPORTED
+ * @param hname If htype specifies PJSIP_H_OTHER, then the header name
+ * must be supplied in this argument. Otherwise the value
+ * must be set to NULL.
+ *
+ * @return The appropriate header, or NULL if the header is not
+ * available.
+ */
+PJ_DECL(const pjsip_hdr*) pjsip_endpt_get_capability( pjsip_endpoint *endpt,
+ int htype,
+ const pj_str_t *hname);
+
+
+/**
+ * Check if we have the specified capability.
+ *
+ * @param endpt The endpoint.
+ * @param htype The header type to be retrieved, which value may be:
+ * - PJSIP_H_ACCEPT
+ * - PJSIP_H_ALLOW
+ * - PJSIP_H_SUPPORTED
+ * @param hname If htype specifies PJSIP_H_OTHER, then the header name
+ * must be supplied in this argument. Otherwise the value
+ * must be set to NULL.
+ * @param token The capability token to check. For example, if \a htype
+ * is PJSIP_H_ALLOW, then \a token specifies the method
+ * names; if \a htype is PJSIP_H_SUPPORTED, then \a token
+ * specifies the extension names such as "100rel".
+ *
+ * @return PJ_TRUE if the specified capability is supported,
+ * otherwise PJ_FALSE..
+ */
+PJ_DECL(pj_bool_t) pjsip_endpt_has_capability( pjsip_endpoint *endpt,
+ int htype,
+ const pj_str_t *hname,
+ const pj_str_t *token);
+
+
+/**
+ * Add or register new capabilities as indicated by the tags to the
+ * appropriate header fields in the endpoint.
+ *
+ * @param endpt The endpoint.
+ * @param mod The module which registers the capability.
+ * @param htype The header type to be set, which value may be:
+ * - PJSIP_H_ACCEPT
+ * - PJSIP_H_ALLOW
+ * - PJSIP_H_SUPPORTED
+ * @param hname If htype specifies PJSIP_H_OTHER, then the header name
+ * must be supplied in this argument. Otherwise the value
+ * must be set to NULL.
+ * @param count The number of tags in the array.
+ * @param tags Array of tags describing the capabilities or extensions
+ * to be added to the appropriate header.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_endpt_add_capability( pjsip_endpoint *endpt,
+ pjsip_module *mod,
+ int htype,
+ const pj_str_t *hname,
+ unsigned count,
+ const pj_str_t tags[]);
+
+/**
+ * Get list of additional headers to be put in outgoing request message.
+ * Currently only Max-Forwards are defined.
+ *
+ * @param e The endpoint.
+ *
+ * @return List of headers.
+ */
+PJ_DECL(const pjsip_hdr*) pjsip_endpt_get_request_headers(pjsip_endpoint *e);
+
+
+/**
+ * Dump endpoint status to the log. This will print the status to the log
+ * with log level 3.
+ *
+ * @param endpt The endpoint.
+ * @param detail If non zero, then it will dump a detailed output.
+ * BEWARE that this option may crash the system because
+ * it tries to access all memory pools.
+ */
+PJ_DECL(void) pjsip_endpt_dump( pjsip_endpoint *endpt, pj_bool_t detail );
+
+
+/**
+ * Register cleanup function to be called by SIP endpoint when
+ * #pjsip_endpt_destroy() is called. Note that application should not
+ * use or access any endpoint resource (such as pool, ioqueue, timer heap)
+ * from within the callback as such resource may have been released when
+ * the callback function is invoked.
+ *
+ * @param endpt The SIP endpoint.
+ * @param func The function to be registered.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_endpt_atexit(pjsip_endpoint *endpt,
+ pjsip_endpt_exit_callback func);
+
+
+/**
+ * @}
+ */
+
+
+/**
+ * Log an error.
+ */
+PJ_DECL(void) pjsip_endpt_log_error( pjsip_endpoint *endpt,
+ const char *sender,
+ pj_status_t error_code,
+ const char *format,
+ ... );
+
+#define PJSIP_ENDPT_LOG_ERROR(expr) \
+ pjsip_endpt_log_error expr
+
+#define PJSIP_ENDPT_TRACE(tracing,expr) \
+ do { \
+ if ((tracing)) \
+ PJ_LOG(4,expr); \
+ } while (0)
+
+/*
+ * Internal functions.
+ */
+/*
+ * Receive transaction events from transactions and put in the event queue
+ * to be processed later.
+ */
+void pjsip_endpt_send_tsx_event( pjsip_endpoint *endpt, pjsip_event *evt );
+
+PJ_END_DECL
+
+#endif /* __PJSIP_SIP_ENDPOINT_H__ */
+
diff --git a/pjsip/include/pjsip/sip_errno.h b/pjsip/include/pjsip/sip_errno.h
new file mode 100644
index 0000000..26e326e
--- /dev/null
+++ b/pjsip/include/pjsip/sip_errno.h
@@ -0,0 +1,545 @@
+/* $Id: sip_errno.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * 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_ERRNO_H__
+#define __PJSIP_SIP_ERRNO_H__
+
+/**
+ * @file sip_errno.h
+ * @brief PJSIP Specific Error Code
+ */
+
+#include <pj/errno.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJSIP_CORE_ERRNO PJSIP Specific Error Code
+ * @ingroup PJSIP_BASE
+ * @brief PJSIP specific error constants.
+ * @{
+ */
+
+/*
+ * PJSIP error codes occupies 170000 - 219000, and mapped as follows:
+ * - 170100 - 170799: mapped to SIP status code in response msg.
+ * - 171000 - 171999: mapped to errors generated from PJSIP core.
+ */
+
+/**
+ * Start of error code relative to PJ_ERRNO_START_USER.
+ */
+#define PJSIP_ERRNO_START (PJ_ERRNO_START_USER)
+
+/**
+ * Create error value from SIP status code.
+ * @param code SIP status code.
+ * @return Error code in pj_status_t namespace.
+ */
+#define PJSIP_ERRNO_FROM_SIP_STATUS(code) (PJSIP_ERRNO_START+code)
+
+/**
+ * Get SIP status code from error value.
+ * If conversion to SIP status code is not available, a SIP status code
+ * 599 will be returned.
+ *
+ * @param status Error code in pj_status_t namespace.
+ * @return SIP status code.
+ */
+#define PJSIP_ERRNO_TO_SIP_STATUS(status) \
+ ((status>=PJSIP_ERRNO_FROM_SIP_STATUS(100) && \
+ status<PJSIP_ERRNO_FROM_SIP_STATUS(800)) ? \
+ status-PJSIP_ERRNO_FROM_SIP_STATUS(0) : 599)
+
+
+/**
+ * Start of PJSIP generated error code values.
+ */
+#define PJSIP_ERRNO_START_PJSIP (PJSIP_ERRNO_START + 1000)
+
+/************************************************************
+ * GENERIC/GENERAL SIP ERRORS
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * SIP object is busy.
+ */
+#define PJSIP_EBUSY (PJSIP_ERRNO_START_PJSIP + 1) /* 171001 */
+/**
+ * @hideinitializer
+ * SIP object with the same type already exists.
+ */
+#define PJSIP_ETYPEEXISTS (PJSIP_ERRNO_START_PJSIP + 2) /* 171002 */
+/**
+ * @hideinitializer
+ * SIP stack is shutting down.
+ */
+#define PJSIP_ESHUTDOWN (PJSIP_ERRNO_START_PJSIP + 3) /* 171003 */
+/**
+ * @hideinitializer
+ * SIP object is not initialized.
+ */
+#define PJSIP_ENOTINITIALIZED (PJSIP_ERRNO_START_PJSIP + 4) /* 171004 */
+/**
+ * @hideinitializer
+ * Missing route set (for tel: URI)
+ */
+#define PJSIP_ENOROUTESET (PJSIP_ERRNO_START_PJSIP + 5) /* 171005 */
+
+
+/************************************************************
+ * MESSAGING ERRORS
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * General invalid message error (e.g. syntax error)
+ */
+#define PJSIP_EINVALIDMSG (PJSIP_ERRNO_START_PJSIP + 20) /* 171020 */
+/**
+ * @hideinitializer
+ * Expecting request message.
+ */
+#define PJSIP_ENOTREQUESTMSG (PJSIP_ERRNO_START_PJSIP + 21) /* 171021 */
+/**
+ * @hideinitializer
+ * Expecting response message.
+ */
+#define PJSIP_ENOTRESPONSEMSG (PJSIP_ERRNO_START_PJSIP + 22) /* 171022 */
+/**
+ * @hideinitializer
+ * Message too long. See also PJSIP_ERXOVERFLOW.
+ */
+#define PJSIP_EMSGTOOLONG (PJSIP_ERRNO_START_PJSIP + 23) /* 171023 */
+/**
+ * @hideinitializer
+ * Message not completely received.
+ */
+#define PJSIP_EPARTIALMSG (PJSIP_ERRNO_START_PJSIP + 24) /* 171024 */
+
+/**
+ * @hideinitializer
+ * Status code is invalid.
+ */
+#define PJSIP_EINVALIDSTATUS (PJSIP_ERRNO_START_PJSIP + 30) /* 171030 */
+
+/**
+ * @hideinitializer
+ * General Invalid URI error.
+ */
+#define PJSIP_EINVALIDURI (PJSIP_ERRNO_START_PJSIP + 39) /* 171039 */
+/**
+ * @hideinitializer
+ * Unsupported URL scheme.
+ */
+#define PJSIP_EINVALIDSCHEME (PJSIP_ERRNO_START_PJSIP + 40) /* 171040 */
+/**
+ * @hideinitializer
+ * Missing Request-URI.
+ */
+#define PJSIP_EMISSINGREQURI (PJSIP_ERRNO_START_PJSIP + 41) /* 171041 */
+/**
+ * @hideinitializer
+ * Invalid request URI.
+ */
+#define PJSIP_EINVALIDREQURI (PJSIP_ERRNO_START_PJSIP + 42) /* 171042 */
+/**
+ * @hideinitializer
+ * URI is too long.
+ */
+#define PJSIP_EURITOOLONG (PJSIP_ERRNO_START_PJSIP + 43) /* 171043 */
+
+/**
+ * @hideinitializer
+ * Missing required header(s).
+ */
+#define PJSIP_EMISSINGHDR (PJSIP_ERRNO_START_PJSIP + 50) /* 171050 */
+/**
+ * @hideinitializer
+ * Invalid header field.
+ */
+#define PJSIP_EINVALIDHDR (PJSIP_ERRNO_START_PJSIP + 51) /* 171051 */
+/**
+ * @hideinitializer
+ * Invalid Via header in response (sent-by, etc).
+ */
+#define PJSIP_EINVALIDVIA (PJSIP_ERRNO_START_PJSIP + 52) /* 171052 */
+/**
+ * @hideinitializer
+ * Multiple Via headers in response.
+ */
+#define PJSIP_EMULTIPLEVIA (PJSIP_ERRNO_START_PJSIP + 53) /* 171053 */
+/**
+ * @hideinitializer
+ * Missing message body.
+ */
+#define PJSIP_EMISSINGBODY (PJSIP_ERRNO_START_PJSIP + 54) /* 171054 */
+/**
+ * @hideinitializer
+ * Invalid/unexpected method.
+ */
+#define PJSIP_EINVALIDMETHOD (PJSIP_ERRNO_START_PJSIP + 55) /* 171055 */
+
+
+/************************************************************
+ * TRANSPORT ERRORS
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * Unsupported transport type.
+ */
+#define PJSIP_EUNSUPTRANSPORT (PJSIP_ERRNO_START_PJSIP + 60) /* 171060 */
+/**
+ * @hideinitializer
+ * Buffer is being sent, operation still pending.
+ */
+#define PJSIP_EPENDINGTX (PJSIP_ERRNO_START_PJSIP + 61) /* 171061 */
+/**
+ * @hideinitializer
+ * Rx buffer overflow. See also PJSIP_EMSGTOOLONG.
+ */
+#define PJSIP_ERXOVERFLOW (PJSIP_ERRNO_START_PJSIP + 62) /* 171062 */
+/**
+ * @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 + 63) /* 171063 */
+/**
+ * @hideinitializer
+ * Unsuitable transport selected. This error occurs when application
+ * has explicitly requested to use a particular transport/listener,
+ * but the selected transport is not suitable to send request to
+ * the specified destination.
+ */
+#define PJSIP_ETPNOTSUITABLE (PJSIP_ERRNO_START_PJSIP + 64) /* 171064 */
+/**
+ * @hideinitializer
+ * Transport not available. This error occurs for example when the SIP stack
+ * is trying to use a SIP transport while the transport is being paused by
+ * application.
+ */
+#define PJSIP_ETPNOTAVAIL (PJSIP_ERRNO_START_PJSIP + 65) /* 171065 */
+
+/************************************************************
+ * TRANSACTION ERRORS
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * Transaction has just been destroyed.
+ */
+#define PJSIP_ETSXDESTROYED (PJSIP_ERRNO_START_PJSIP + 70) /* 171070 */
+/**
+ * @hideinitializer
+ * No transaction.
+ */
+#define PJSIP_ENOTSX (PJSIP_ERRNO_START_PJSIP + 71) /* 171071 */
+
+
+/************************************************************
+ * URI COMPARISON RESULTS
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * Scheme mismatch.
+ */
+#define PJSIP_ECMPSCHEME (PJSIP_ERRNO_START_PJSIP + 80) /* 171080 */
+/**
+ * @hideinitializer
+ * User part mismatch.
+ */
+#define PJSIP_ECMPUSER (PJSIP_ERRNO_START_PJSIP + 81) /* 171081 */
+/**
+ * @hideinitializer
+ * Password part mismatch.
+ */
+#define PJSIP_ECMPPASSWD (PJSIP_ERRNO_START_PJSIP + 82) /* 171082 */
+/**
+ * @hideinitializer
+ * Host part mismatch.
+ */
+#define PJSIP_ECMPHOST (PJSIP_ERRNO_START_PJSIP + 83) /* 171083 */
+/**
+ * @hideinitializer
+ * Port part mismatch.
+ */
+#define PJSIP_ECMPPORT (PJSIP_ERRNO_START_PJSIP + 84) /* 171084 */
+/**
+ * @hideinitializer
+ * Transport parameter part mismatch.
+ */
+#define PJSIP_ECMPTRANSPORTPRM (PJSIP_ERRNO_START_PJSIP + 85) /* 171085 */
+/**
+ * @hideinitializer
+ * TTL parameter part mismatch.
+ */
+#define PJSIP_ECMPTTLPARAM (PJSIP_ERRNO_START_PJSIP + 86) /* 171086 */
+/**
+ * @hideinitializer
+ * User parameter part mismatch.
+ */
+#define PJSIP_ECMPUSERPARAM (PJSIP_ERRNO_START_PJSIP + 87) /* 171087 */
+/**
+ * @hideinitializer
+ * Method parameter part mismatch.
+ */
+#define PJSIP_ECMPMETHODPARAM (PJSIP_ERRNO_START_PJSIP + 88) /* 171088 */
+/**
+ * @hideinitializer
+ * Maddr parameter part mismatch.
+ */
+#define PJSIP_ECMPMADDRPARAM (PJSIP_ERRNO_START_PJSIP + 89) /* 171089 */
+/**
+ * @hideinitializer
+ * Parameter part in other_param mismatch.
+ */
+#define PJSIP_ECMPOTHERPARAM (PJSIP_ERRNO_START_PJSIP + 90) /* 171090 */
+/**
+ * @hideinitializer
+ * Parameter part in header_param mismatch.
+ */
+#define PJSIP_ECMPHEADERPARAM (PJSIP_ERRNO_START_PJSIP + 91) /* 171091 */
+
+
+/************************************************************
+ * AUTHENTICATION FRAMEWORK
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * Credential failed to authenticate. For this failure, right credential
+ * for the realm has been found and used to authenticate against the challenge,
+ * but the server has rejected the authorization request with 401/407 response
+ * (either with no stale parameter or with "stale=false" parameter). In most
+ * cases, this indicates that the username/password combination is incorrect.
+ */
+#define PJSIP_EFAILEDCREDENTIAL (PJSIP_ERRNO_START_PJSIP + 100) /* 171100 */
+/**
+ * @hideinitializer
+ * No suitable credential is found to authenticate the request against
+ * the received authentication challenge in 401/407 response. This often
+ * is caused by different realm supplied in the credential than the realm
+ * found in the challenge.
+ */
+#define PJSIP_ENOCREDENTIAL (PJSIP_ERRNO_START_PJSIP + 101) /* 171101 */
+/**
+ * @hideinitializer
+ * Invalid/unsupported algorithm.
+ */
+#define PJSIP_EINVALIDALGORITHM (PJSIP_ERRNO_START_PJSIP + 102) /* 171102 */
+/**
+ * @hideinitializer
+ * Invalid/unsupported qop.
+ */
+#define PJSIP_EINVALIDQOP (PJSIP_ERRNO_START_PJSIP + 103) /* 171103 */
+/**
+ * @hideinitializer
+ * Invalid/unsupported authentication scheme.
+ */
+#define PJSIP_EINVALIDAUTHSCHEME (PJSIP_ERRNO_START_PJSIP + 104)/* 171104 */
+/**
+ * @hideinitializer
+ * No previous challenge.
+ */
+#define PJSIP_EAUTHNOPREVCHAL (PJSIP_ERRNO_START_PJSIP + 105) /* 171105 */
+/**
+ * @hideinitializer
+ * No authorization is found.
+ */
+#define PJSIP_EAUTHNOAUTH (PJSIP_ERRNO_START_PJSIP + 106) /* 171106 */
+/**
+ * @hideinitializer
+ * Account not found.
+ */
+#define PJSIP_EAUTHACCNOTFOUND (PJSIP_ERRNO_START_PJSIP + 107) /* 171107 */
+/**
+ * @hideinitializer
+ * Account is disabled.
+ */
+#define PJSIP_EAUTHACCDISABLED (PJSIP_ERRNO_START_PJSIP + 108) /* 171108 */
+/**
+ * @hideinitializer
+ * Invalid realm.
+ */
+#define PJSIP_EAUTHINVALIDREALM (PJSIP_ERRNO_START_PJSIP + 109) /* 171109 */
+/**
+ * @hideinitializer
+ * Invalid digest.
+ */
+#define PJSIP_EAUTHINVALIDDIGEST (PJSIP_ERRNO_START_PJSIP+110) /* 171110 */
+/**
+ * @hideinitializer
+ * Maximum number of stale retries exceeded. This happens when server
+ * keeps rejecting our authorization request with stale=true.
+ */
+#define PJSIP_EAUTHSTALECOUNT (PJSIP_ERRNO_START_PJSIP + 111) /* 171111 */
+/**
+ * @hideinitializer
+ * Invalid nonce value in the challenge.
+ */
+#define PJSIP_EAUTHINNONCE (PJSIP_ERRNO_START_PJSIP + 112) /* 171112 */
+/**
+ * @hideinitializer
+ * Invalid AKA credential.
+ */
+#define PJSIP_EAUTHINAKACRED (PJSIP_ERRNO_START_PJSIP + 113) /* 171113 */
+/**
+ * No challenge is found in the challenge.
+ */
+#define PJSIP_EAUTHNOCHAL (PJSIP_ERRNO_START_PJSIP + 114) /* 171114 */
+
+/************************************************************
+ * UA AND DIALOG ERRORS
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * Missing From/To tag.
+ */
+#define PJSIP_EMISSINGTAG (PJSIP_ERRNO_START_PJSIP+120) /* 171120 */
+/**
+ * @hideinitializer
+ * Expecting REFER method
+ */
+#define PJSIP_ENOTREFER (PJSIP_ERRNO_START_PJSIP+121) /* 171121 */
+/**
+ * @hideinitializer
+ * Not associated with REFER subscription
+ */
+#define PJSIP_ENOREFERSESSION (PJSIP_ERRNO_START_PJSIP+122) /* 171122 */
+
+/************************************************************
+ * INVITE SESSIONS ERRORS
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * Session already terminated.
+ */
+#define PJSIP_ESESSIONTERMINATED (PJSIP_ERRNO_START_PJSIP+140) /* 171140 */
+/**
+ * @hideinitializer
+ * Invalid session state for the specified operation.
+ */
+#define PJSIP_ESESSIONSTATE (PJSIP_ERRNO_START_PJSIP+141) /* 171141 */
+/**
+ * @hideinitializer
+ * The feature being requested requires the use of secure session or
+ * transport.
+ */
+#define PJSIP_ESESSIONINSECURE (PJSIP_ERRNO_START_PJSIP+142) /* 171142 */
+
+/************************************************************
+ * TLS TRANSPORT ERRORS
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * Unknown TLS error
+ */
+#define PJSIP_TLS_EUNKNOWN (PJSIP_ERRNO_START_PJSIP+160) /* 171160 */
+/**
+ * @hideinitializer
+ * Invalid SSL protocol method.
+ */
+#define PJSIP_TLS_EINVMETHOD (PJSIP_ERRNO_START_PJSIP+161) /* 171161 */
+/**
+ * @hideinitializer
+ * Error loading/verifying SSL CA list file.
+ */
+#define PJSIP_TLS_ECACERT (PJSIP_ERRNO_START_PJSIP+162) /* 171162 */
+/**
+ * @hideinitializer
+ * Error loading SSL certificate chain file.
+ */
+#define PJSIP_TLS_ECERTFILE (PJSIP_ERRNO_START_PJSIP+163) /* 171163 */
+/**
+ * @hideinitializer
+ * Error adding private key from SSL certificate file.
+ */
+#define PJSIP_TLS_EKEYFILE (PJSIP_ERRNO_START_PJSIP+164) /* 171164 */
+/**
+ * @hideinitializer
+ * Error setting SSL cipher list.
+ */
+#define PJSIP_TLS_ECIPHER (PJSIP_ERRNO_START_PJSIP+165) /* 171165 */
+/**
+ * @hideinitializer
+ * Error creating SSL context.
+ */
+#define PJSIP_TLS_ECTX (PJSIP_ERRNO_START_PJSIP+166) /* 171166 */
+/**
+ * @hideinitializer
+ * Error creating SSL connection object.
+ */
+#define PJSIP_TLS_ESSLCONN (PJSIP_ERRNO_START_PJSIP+167) /* 171167 */
+/**
+ * @hideinitializer
+ * Unknown error when performing SSL connect().
+ */
+#define PJSIP_TLS_ECONNECT (PJSIP_ERRNO_START_PJSIP+168) /* 171168 */
+/**
+ * @hideinitializer
+ * Unknown error when performing SSL accept().
+ */
+#define PJSIP_TLS_EACCEPT (PJSIP_ERRNO_START_PJSIP+169) /* 171169 */
+/**
+ * @hideinitializer
+ * Unknown error when sending SSL data
+ */
+#define PJSIP_TLS_ESEND (PJSIP_ERRNO_START_PJSIP+170) /* 171170 */
+/**
+ * @hideinitializer
+ * Unknown error when reading SSL data
+ */
+#define PJSIP_TLS_EREAD (PJSIP_ERRNO_START_PJSIP+171) /* 171171 */
+/**
+ * @hideinitializer
+ * SSL negotiation has exceeded the maximum configured timeout.
+ */
+#define PJSIP_TLS_ETIMEDOUT (PJSIP_ERRNO_START_PJSIP+172) /* 171172 */
+/**
+ * @hideinitializer
+ * SSL certificate verification error.
+ */
+#define PJSIP_TLS_ECERTVERIF (PJSIP_ERRNO_START_PJSIP+173) /* 171173 */
+
+
+/**
+ * Get error message for the specified error code. Note that this
+ * function is only able to decode PJSIP specific error code.
+ * Application should use pj_strerror(), which should be able to
+ * decode all error codes belonging to all subsystems (e.g. pjlib,
+ * pjmedia, pjsip, etc).
+ *
+ * @param status The error code.
+ * @param buffer The buffer where to put the error message.
+ * @param bufsize Size of the buffer.
+ *
+ * @return The error message as NULL terminated string,
+ * wrapped with pj_str_t.
+ */
+PJ_DECL(pj_str_t) pjsip_strerror(pj_status_t status,
+ char *buffer, pj_size_t bufsize);
+
+
+PJ_END_DECL
+
+
+/**
+ * @}
+ */
+
+#endif /* __PJSIP_SIP_ERRNO_H__ */
+
diff --git a/pjsip/include/pjsip/sip_event.h b/pjsip/include/pjsip/sip_event.h
new file mode 100644
index 0000000..d6c90af
--- /dev/null
+++ b/pjsip/include/pjsip/sip_event.h
@@ -0,0 +1,231 @@
+/* $Id: sip_event.h 4154 2012-06-05 10:41:17Z bennylp $ */
+/*
+ * 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_EVENT_H__
+#define __PJSIP_SIP_EVENT_H__
+
+/**
+ * @file sip_event.h
+ * @brief SIP Event
+ */
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJSIP_EVENT Event
+ * @ingroup PJSIP_CORE_CORE
+ * @brief Representation of events as they are distributed among modules.
+ * @{
+ */
+#include <pj/types.h>
+#include <pj/timer.h>
+
+
+/**
+ * Event IDs.
+ */
+typedef enum pjsip_event_id_e
+{
+ /** Unidentified event. */
+ PJSIP_EVENT_UNKNOWN,
+
+ /** Timer event, normally only used internally in transaction. */
+ PJSIP_EVENT_TIMER,
+
+ /** Message transmission event. */
+ PJSIP_EVENT_TX_MSG,
+
+ /** Message received event. */
+ PJSIP_EVENT_RX_MSG,
+
+ /** Transport error event. */
+ PJSIP_EVENT_TRANSPORT_ERROR,
+
+ /** Transaction state changed event. */
+ PJSIP_EVENT_TSX_STATE,
+
+ /** Indicates that the event was triggered by user action. */
+ PJSIP_EVENT_USER
+
+} pjsip_event_id_e;
+
+
+/**
+ * This structure describe event descriptor to fully identify a SIP event.
+ *
+ * Events are the only way for a lower layer object to inform something
+ * to higher layer objects. Normally this is achieved by means of callback,
+ * i.e. the higher layer objects register a callback to handle the event on
+ * the lower layer objects.
+ *
+ * This event descriptor is used for example by transactions, to inform
+ * endpoint about events, and by transports, to inform endpoint about
+ * unexpected transport error.
+ */
+struct pjsip_event
+{
+ /** This is necessary so that we can put events as a list. */
+ PJ_DECL_LIST_MEMBER(struct pjsip_event);
+
+ /** The event type, can be any value of \b pjsip_event_id_e.
+ */
+ pjsip_event_id_e type;
+
+ /**
+ * The event body as union, which fields depends on the event type.
+ * By convention, the first member of each struct in the union must be
+ * the pointer which is relevant to the event.
+ */
+ union
+ {
+ /** Timer event. */
+ struct
+ {
+ pj_timer_entry *entry; /**< The timer entry. */
+ } timer;
+
+ /** Transaction state has changed event. */
+ struct
+ {
+ union
+ {
+ pjsip_rx_data *rdata; /**< The incoming message. */
+ pjsip_tx_data *tdata; /**< The outgoing message. */
+ pj_timer_entry *timer; /**< The timer. */
+ pj_status_t status;/**< Transport error status. */
+ void *data; /**< Generic data. */
+ } src;
+ pjsip_transaction *tsx; /**< The transaction. */
+ int prev_state; /**< Previous state. */
+ pjsip_event_id_e type; /**< Type of event source:
+ * - PJSIP_EVENT_TX_MSG
+ * - PJSIP_EVENT_RX_MSG,
+ * - PJSIP_EVENT_TRANSPORT_ERROR
+ * - PJSIP_EVENT_TIMER
+ * - PJSIP_EVENT_USER
+ */
+ } tsx_state;
+
+ /** Message transmission event. */
+ struct
+ {
+ pjsip_tx_data *tdata; /**< The transmit data buffer. */
+
+ } tx_msg;
+
+ /** Transmission error event. */
+ struct
+ {
+ pjsip_tx_data *tdata; /**< The transmit data. */
+ pjsip_transaction *tsx; /**< The transaction. */
+ } tx_error;
+
+ /** Message arrival event. */
+ struct
+ {
+ pjsip_rx_data *rdata; /**< The receive data buffer. */
+ } rx_msg;
+
+ /** User event. */
+ struct
+ {
+ void *user1; /**< User data 1. */
+ void *user2; /**< User data 2. */
+ void *user3; /**< User data 3. */
+ void *user4; /**< User data 4. */
+ } user;
+
+ } body;
+};
+
+/**
+ * Init timer event.
+ */
+#define PJSIP_EVENT_INIT_TIMER(event,pentry) \
+ do { \
+ (event).type = PJSIP_EVENT_TIMER; \
+ (event).body.timer.entry = pentry; \
+ } while (0)
+
+/**
+ * Init tsx state event.
+ */
+#define PJSIP_EVENT_INIT_TSX_STATE(event,ptsx,ptype,pdata,prev) \
+ do { \
+ (event).type = PJSIP_EVENT_TSX_STATE; \
+ (event).body.tsx_state.tsx = ptsx; \
+ (event).body.tsx_state.type = ptype; \
+ (event).body.tsx_state.src.data = pdata; \
+ (event).body.tsx_state.prev_state = prev; \
+ } while (0)
+
+/**
+ * Init tx msg event.
+ */
+#define PJSIP_EVENT_INIT_TX_MSG(event,ptdata) \
+ do { \
+ (event).type = PJSIP_EVENT_TX_MSG; \
+ (event).body.tx_msg.tdata = ptdata; \
+ } while (0)
+
+/**
+ * Init rx msg event.
+ */
+#define PJSIP_EVENT_INIT_RX_MSG(event,prdata) \
+ do { \
+ (event).type = PJSIP_EVENT_RX_MSG; \
+ (event).body.rx_msg.rdata = prdata; \
+ } while (0)
+
+/**
+ * Init transport error event.
+ */
+#define PJSIP_EVENT_INIT_TRANSPORT_ERROR(event,ptsx,ptdata) \
+ do { \
+ (event).type = PJSIP_EVENT_TRANSPORT_ERROR; \
+ (event).body.tx_error.tsx = ptsx; \
+ (event).body.tx_error.tdata = ptdata; \
+ } while (0)
+
+/**
+ * Init user event.
+ */
+#define PJSIP_EVENT_INIT_USER(event,u1,u2,u3,u4) \
+ do { \
+ (event).type = PJSIP_EVENT_USER; \
+ (event).body.user.user1 = (void*)u1; \
+ (event).body.user.user2 = (void*)u2; \
+ (event).body.user.user3 = (void*)u3; \
+ (event).body.user.user4 = (void*)u4; \
+ } while (0)
+
+/**
+ * Get the event string from the event ID.
+ * @param e the event ID.
+ * @note defined in sip_util.c
+ */
+PJ_DECL(const char *) pjsip_event_str(pjsip_event_id_e e);
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+#endif /* __PJSIP_SIP_EVENT_H__ */
diff --git a/pjsip/include/pjsip/sip_module.h b/pjsip/include/pjsip/sip_module.h
new file mode 100644
index 0000000..45884cc
--- /dev/null
+++ b/pjsip/include/pjsip/sip_module.h
@@ -0,0 +1,222 @@
+/* $Id: sip_module.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * 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_MODULE_H__
+#define __PJSIP_SIP_MODULE_H__
+
+/**
+ * @file sip_module.h
+ * @brief Module helpers
+ */
+#include <pjsip/sip_types.h>
+#include <pj/list.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJSIP_MOD Modules
+ * @ingroup PJSIP_CORE_CORE
+ * @brief Modules are the primary means to extend PJSIP!
+ * @{
+ * Modules are the primary means to extend PJSIP. Without modules, PJSIP
+ * would not know how to handle messages, and will simply discard all
+ * incoming messages.
+ *
+ * Modules are registered by creating and initializing #pjsip_module
+ * structure, and register the structure to PJSIP with
+ * #pjsip_endpt_register_module().
+ *
+ * The <A HREF="/docs.htm">PJSIP Developer's Guide</A>
+ * has a thorough discussion on this subject, and readers are encouraged
+ * to read the document for more information.
+ */
+
+/**
+ * The declaration for SIP module. This structure would be passed to
+ * #pjsip_endpt_register_module() to register the module to PJSIP.
+ */
+struct pjsip_module
+{
+ /** To allow chaining of modules in the endpoint. */
+ PJ_DECL_LIST_MEMBER(struct pjsip_module);
+
+ /**
+ * Module name to identify the module.
+ *
+ * This field MUST be initialized before registering the module.
+ */
+ pj_str_t name;
+
+ /**
+ * Module ID. Application must initialize this field with -1 before
+ * registering the module to PJSIP. After the module is registered,
+ * this field will contain a unique ID to identify the module.
+ */
+ 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.
+ *
+ * This field MUST be initialized before registering the module.
+ */
+ int priority;
+
+ /**
+ * Optional function to be called to initialize the module. This function
+ * will be called by endpoint during module registration. If the value
+ * is NULL, then it's equal to returning PJ_SUCCESS.
+ *
+ * @param endpt The endpoint instance.
+ * @return Module should return PJ_SUCCESS to indicate success.
+ */
+ pj_status_t (*load)(pjsip_endpoint *endpt);
+
+ /**
+ * Optional function to be called to start the module. This function
+ * will be called by endpoint during module registration. If the value
+ * is NULL, then it's equal to returning PJ_SUCCESS.
+ *
+ * @return Module should return zero to indicate success.
+ */
+ pj_status_t (*start)(void);
+
+ /**
+ * Optional function to be called to deinitialize the module before
+ * it is unloaded. This function will be called by endpoint during
+ * module unregistration. If the value is NULL, then it's equal to
+ * returning PJ_SUCCESS.
+ *
+ * @return Module should return PJ_SUCCESS to indicate success.
+ */
+ pj_status_t (*stop)(void);
+
+ /**
+ * Optional function to be called to deinitialize the module before
+ * it is unloaded. This function will be called by endpoint during
+ * module unregistration. If the value is NULL, then it's equal to
+ * returning PJ_SUCCESS.
+ *
+ * @param mod The module.
+ *
+ * @return Module should return PJ_SUCCESS to indicate success.
+ */
+ pj_status_t (*unload)(void);
+
+ /**
+ * Optional function to be called to process incoming request message.
+ *
+ * @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.
+ */
+ pj_bool_t (*on_rx_request)(pjsip_rx_data *rdata);
+
+ /**
+ * Optional function to be called to process incoming response message.
+ *
+ * @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);
+
+ /**
+ * Optional function to be called when transport layer is about to
+ * transmit outgoing request message.
+ *
+ * @param tdata The outgoing request message.
+ *
+ * @return Module should return PJ_SUCCESS in all cases.
+ * If non-zero (or PJ_FALSE) is returned, the message
+ * will not be sent.
+ */
+ pj_status_t (*on_tx_request)(pjsip_tx_data *tdata);
+
+ /**
+ * Optional function to be called when transport layer is about to
+ * transmit outgoing response message.
+ *
+ * @param tdata The outgoing response message.
+ *
+ * @return Module should return PJ_SUCCESS in all cases.
+ * If non-zero (or PJ_FALSE) is returned, the message
+ * will not be sent.
+ */
+ pj_status_t (*on_tx_response)(pjsip_tx_data *tdata);
+
+ /**
+ * Optional function to be 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);
+
+};
+
+
+/**
+ * Module priority guidelines.
+ */
+enum pjsip_module_priority
+{
+ /**
+ * This is the priority used by transport layer.
+ */
+ PJSIP_MOD_PRIORITY_TRANSPORT_LAYER = 8,
+
+ /**
+ * This is the priority used by transaction layer.
+ */
+ PJSIP_MOD_PRIORITY_TSX_LAYER = 16,
+
+ /**
+ * This is the priority used by the user agent and proxy layer.
+ */
+ PJSIP_MOD_PRIORITY_UA_PROXY_LAYER = 32,
+
+ /**
+ * This is the priority used by the dialog usages.
+ */
+ PJSIP_MOD_PRIORITY_DIALOG_USAGE = 48,
+
+ /**
+ * This is the recommended priority to be used by applications.
+ */
+ PJSIP_MOD_PRIORITY_APPLICATION = 64
+};
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+#endif /* __PJSIP_SIP_MODULE_H__ */
+
diff --git a/pjsip/include/pjsip/sip_msg.h b/pjsip/include/pjsip/sip_msg.h
new file mode 100644
index 0000000..9031fa2
--- /dev/null
+++ b/pjsip/include/pjsip/sip_msg.h
@@ -0,0 +1,2048 @@
+/* $Id: sip_msg.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * 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_MSG_H__
+#define __PJSIP_SIP_MSG_H__
+
+/**
+ * @file pjsip/sip_msg.h
+ * @brief SIP Message Structure.
+ */
+
+#include <pjsip/sip_types.h>
+#include <pjsip/sip_uri.h>
+#include <pj/list.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJSIP_MSG Messaging Elements
+ * @ingroup PJSIP_CORE
+ * @brief Various SIP message elements such as methods, headers, URIs, etc.
+ * @{
+ */
+
+/* **************************************************************************/
+/**
+ * @defgroup PJSIP_MSG_METHOD Methods
+ * @brief Method names and manipulation.
+ * @ingroup PJSIP_MSG
+ * @{
+ */
+
+/**
+ * This enumeration declares SIP methods as described by RFC3261. Additional
+ * methods do exist, and they are described by corresponding RFCs for the SIP
+ * extentensions. Since they won't alter the characteristic of the processing
+ * of the message, they don't need to be explicitly mentioned here.
+ */
+typedef enum pjsip_method_e
+{
+ 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. */
+
+ PJSIP_OTHER_METHOD /**< Other method. */
+
+} pjsip_method_e;
+
+
+
+/**
+ * This structure represents a SIP method.
+ * Application must always use either #pjsip_method_init or #pjsip_method_set
+ * to make sure that method name is initialized correctly. This way, the name
+ * member will always contain a valid method string regardless whether the ID
+ * is recognized or not.
+ */
+struct pjsip_method
+{
+ pjsip_method_e id; /**< Method ID, from \a pjsip_method_e. */
+ pj_str_t name; /**< Method name, which will always contain the
+ method string. */
+};
+
+
+/*
+ * For convenience, standard method structures are defined in the library.
+ */
+/** INVITE method constant. @see pjsip_get_invite_method() */
+PJ_DECL_DATA(const pjsip_method) pjsip_invite_method;
+
+/** CANCEL method constant. @see pjsip_get_cancel_method() */
+PJ_DECL_DATA(const pjsip_method) pjsip_cancel_method;
+
+/** ACK method constant. @see pjsip_get_ack_method() */
+PJ_DECL_DATA(const pjsip_method) pjsip_ack_method;
+
+/** BYE method constant. @see pjsip_get_bye_method() */
+PJ_DECL_DATA(const pjsip_method) pjsip_bye_method;
+
+/** REGISTER method constant. @see pjsip_get_register_method() */
+PJ_DECL_DATA(const pjsip_method) pjsip_register_method;
+
+/** OPTIONS method constant. @see pjsip_get_options_method() */
+PJ_DECL_DATA(const pjsip_method) pjsip_options_method;
+
+/*
+ * Accessor functions for standard SIP methods.
+ */
+/** Get INVITE method constant. */
+PJ_DECL(const pjsip_method*) pjsip_get_invite_method(void);
+/** Get CANCEL method constant. */
+PJ_DECL(const pjsip_method*) pjsip_get_cancel_method(void);
+/** Get ACK method constant. */
+PJ_DECL(const pjsip_method*) pjsip_get_ack_method(void);
+/** Get BYE method constant. */
+PJ_DECL(const pjsip_method*) pjsip_get_bye_method(void);
+/** Get REGISTER method constant.*/
+PJ_DECL(const pjsip_method*) pjsip_get_register_method(void);
+/** Get OPTIONS method constant. */
+PJ_DECL(const pjsip_method*) pjsip_get_options_method(void);
+
+
+/*
+ * Accessor functions
+ */
+
+/**
+ * Initialize the method structure from a string.
+ * This function will check whether the method is a known method then set
+ * both the id and name accordingly.
+ *
+ * @param m The method to initialize.
+ * @param pool Pool where memory allocation will be allocated from, if required.
+ * @param str The method string.
+ */
+PJ_DECL(void) pjsip_method_init( pjsip_method *m,
+ pj_pool_t *pool,
+ const pj_str_t *str);
+
+/**
+ * Initialize the method structure from a string, without cloning the string.
+ * See #pjsip_method_init.
+ *
+ * @param m The method structure to be initialized.
+ * @param str The method string.
+ */
+PJ_DECL(void) pjsip_method_init_np( pjsip_method *m,
+ pj_str_t *str);
+
+/**
+ * Set the method with the predefined method ID.
+ * This function will also set the name member of the structure to the correct
+ * string according to the method.
+ *
+ * @param m The method structure.
+ * @param id The method ID.
+ */
+PJ_DECL(void) pjsip_method_set( pjsip_method *m, pjsip_method_e id );
+
+
+/**
+ * Copy one method structure to another. If the method is of the known methods,
+ * then memory allocation is not required.
+ *
+ * @param pool Pool to allocate memory from, if required.
+ * @param method The destination method to copy to.
+ * @param rhs The source method to copy from.
+ */
+PJ_DECL(void) pjsip_method_copy( pj_pool_t *pool,
+ pjsip_method *method,
+ const pjsip_method *rhs );
+
+/**
+ * Compare one method with another, and conveniently determine whether the
+ * first method is equal, less than, or greater than the second method.
+ *
+ * @param m1 The first method.
+ * @param m2 The second method.
+ *
+ * @return Zero if equal, otherwise will return -1 if less or +1 if greater.
+ */
+PJ_DECL(int) pjsip_method_cmp( const pjsip_method *m1, const pjsip_method *m2);
+
+/**
+ * @}
+ */
+
+/* **************************************************************************/
+/**
+ * @defgroup PJSIP_MSG_HDR Header Fields
+ * @brief Declarations for various SIP header fields.
+ * @ingroup PJSIP_MSG
+ * @{
+ */
+
+/**
+ * Header types, as defined by RFC3261.
+ */
+typedef enum pjsip_hdr_e
+{
+ /*
+ * These are the headers documented in RFC3261. Headers not documented
+ * there must have type PJSIP_H_OTHER, and the header type itself is
+ * recorded in the header name string.
+ *
+ * DO NOT CHANGE THE VALUE/ORDER OF THE HEADER IDs!!!.
+ */
+ PJSIP_H_ACCEPT,
+ PJSIP_H_ACCEPT_ENCODING_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_ACCEPT_LANGUAGE_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_ALERT_INFO_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_ALLOW,
+ PJSIP_H_AUTHENTICATION_INFO_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_AUTHORIZATION,
+ PJSIP_H_CALL_ID,
+ PJSIP_H_CALL_INFO_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_CONTACT,
+ PJSIP_H_CONTENT_DISPOSITION_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_CONTENT_ENCODING_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_CONTENT_LANGUAGE_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_CONTENT_LENGTH,
+ PJSIP_H_CONTENT_TYPE,
+ PJSIP_H_CSEQ,
+ PJSIP_H_DATE_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_ERROR_INFO_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_EXPIRES,
+ PJSIP_H_FROM,
+ PJSIP_H_IN_REPLY_TO_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_MAX_FORWARDS,
+ PJSIP_H_MIME_VERSION_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_MIN_EXPIRES,
+ PJSIP_H_ORGANIZATION_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_PRIORITY_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_PROXY_AUTHENTICATE,
+ PJSIP_H_PROXY_AUTHORIZATION,
+ PJSIP_H_PROXY_REQUIRE_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_RECORD_ROUTE,
+ PJSIP_H_REPLY_TO_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_REQUIRE,
+ PJSIP_H_RETRY_AFTER,
+ PJSIP_H_ROUTE,
+ PJSIP_H_SERVER_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_SUBJECT_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_SUPPORTED,
+ PJSIP_H_TIMESTAMP_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_TO,
+ PJSIP_H_UNSUPPORTED,
+ PJSIP_H_USER_AGENT_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_VIA,
+ PJSIP_H_WARNING_UNIMP, /* N/A, use pjsip_generic_string_hdr */
+ PJSIP_H_WWW_AUTHENTICATE,
+
+ PJSIP_H_OTHER
+
+} pjsip_hdr_e;
+
+/**
+ * This structure provides the pointer to basic functions that are needed
+ * for generic header operations. All header fields will have pointer to
+ * this structure, so that they can be manipulated uniformly.
+ */
+typedef struct pjsip_hdr_vptr
+{
+ /**
+ * Function to clone the header.
+ *
+ * @param pool Memory pool to allocate the new header.
+ * @param hdr Header to clone.
+ *
+ * @return A new instance of the header.
+ */
+ void *(*clone)(pj_pool_t *pool, const void *hdr);
+
+ /**
+ * Pointer to function to shallow clone the header.
+ * Shallow cloning will just make a memory copy of the original header,
+ * thus all pointers in original header will be kept intact. Because the
+ * function does not need to perform deep copy, the operation should be
+ * faster, but the application must make sure that the original header
+ * is still valid throughout the lifetime of new header.
+ *
+ * @param pool Memory pool to allocate the new header.
+ * @param hdr The header to clone.
+ */
+ void *(*shallow_clone)(pj_pool_t *pool, const void *hdr);
+
+ /** Pointer to function to print the header to the specified buffer.
+ * Returns the length of string written, or -1 if the remaining buffer
+ * is not enough to hold the header.
+ *
+ * @param hdr The header to print.
+ * @param buf The buffer.
+ * @param len The size of the buffer.
+ *
+ * @return The size copied to buffer, or -1 if there's not enough space.
+ */
+ int (*print_on)(void *hdr, char *buf, pj_size_t len);
+
+} pjsip_hdr_vptr;
+
+
+/**
+ * Generic fields for all SIP headers are declared using this macro, to make
+ * sure that all headers will have exactly the same layout in their start of
+ * the storage. This behaves like C++ inheritance actually.
+ */
+#define PJSIP_DECL_HDR_MEMBER(hdr) \
+ /** List members. */ \
+ PJ_DECL_LIST_MEMBER(hdr); \
+ /** Header type */ \
+ pjsip_hdr_e type; \
+ /** Header name. */ \
+ pj_str_t name; \
+ /** Header short name version. */ \
+ pj_str_t sname; \
+ /** Virtual function table. */ \
+ pjsip_hdr_vptr *vptr
+
+
+/**
+ * Generic SIP header structure, for generic manipulation for headers in the
+ * message. All header fields can be typecasted to this type.
+ */
+struct pjsip_hdr
+{
+ PJSIP_DECL_HDR_MEMBER(struct pjsip_hdr);
+};
+
+
+/**
+ * This generic function will clone any header, by calling "clone" function
+ * in header's virtual function table.
+ *
+ * @param pool The pool to allocate memory from.
+ * @param hdr The header to clone.
+ *
+ * @return A new instance copied from the original header.
+ */
+PJ_DECL(void*) pjsip_hdr_clone( pj_pool_t *pool, const void *hdr );
+
+
+/**
+ * This generic function will clone any header, by calling "shallow_clone"
+ * function in header's virtual function table.
+ *
+ * @param pool The pool to allocate memory from.
+ * @param hdr The header to clone.
+ *
+ * @return A new instance copied from the original header.
+ */
+PJ_DECL(void*) pjsip_hdr_shallow_clone( pj_pool_t *pool, const void *hdr );
+
+/**
+ * This generic function will print any header, by calling "print"
+ * function in header's virtual function table.
+ *
+ * @param hdr The header to print.
+ * @param buf The buffer.
+ * @param len The size of the buffer.
+ *
+ * @return The size copied to buffer, or -1 if there's not enough space.
+ */
+PJ_DECL(int) pjsip_hdr_print_on( void *hdr, char *buf, pj_size_t len);
+
+/**
+ * @}
+ */
+
+/* **************************************************************************/
+/**
+ * @defgroup PJSIP_MSG_LINE Request and Status Line.
+ * @brief Request and status line structures and manipulation.
+ * @ingroup PJSIP_MSG
+ * @{
+ */
+
+/**
+ * This structure describes SIP request line.
+ */
+typedef struct pjsip_request_line
+{
+ pjsip_method method; /**< Method for this request line. */
+ pjsip_uri *uri; /**< URI for this request line. */
+} pjsip_request_line;
+
+
+/**
+ * This structure describes SIP status line.
+ */
+typedef struct pjsip_status_line
+{
+ int code; /**< Status code. */
+ pj_str_t reason; /**< Reason string. */
+} pjsip_status_line;
+
+
+/**
+ * This enumeration lists standard SIP status codes according to RFC 3261.
+ * In addition, it also declares new status class 7xx for errors generated
+ * by the stack. This status class however should not get transmitted on the
+ * wire.
+ */
+typedef enum pjsip_status_code
+{
+ PJSIP_SC_TRYING = 100,
+ PJSIP_SC_RINGING = 180,
+ PJSIP_SC_CALL_BEING_FORWARDED = 181,
+ PJSIP_SC_QUEUED = 182,
+ PJSIP_SC_PROGRESS = 183,
+
+ PJSIP_SC_OK = 200,
+ PJSIP_SC_ACCEPTED = 202,
+
+ PJSIP_SC_MULTIPLE_CHOICES = 300,
+ PJSIP_SC_MOVED_PERMANENTLY = 301,
+ PJSIP_SC_MOVED_TEMPORARILY = 302,
+ PJSIP_SC_USE_PROXY = 305,
+ PJSIP_SC_ALTERNATIVE_SERVICE = 380,
+
+ PJSIP_SC_BAD_REQUEST = 400,
+ PJSIP_SC_UNAUTHORIZED = 401,
+ PJSIP_SC_PAYMENT_REQUIRED = 402,
+ PJSIP_SC_FORBIDDEN = 403,
+ PJSIP_SC_NOT_FOUND = 404,
+ PJSIP_SC_METHOD_NOT_ALLOWED = 405,
+ PJSIP_SC_NOT_ACCEPTABLE = 406,
+ PJSIP_SC_PROXY_AUTHENTICATION_REQUIRED = 407,
+ PJSIP_SC_REQUEST_TIMEOUT = 408,
+ PJSIP_SC_GONE = 410,
+ PJSIP_SC_REQUEST_ENTITY_TOO_LARGE = 413,
+ PJSIP_SC_REQUEST_URI_TOO_LONG = 414,
+ PJSIP_SC_UNSUPPORTED_MEDIA_TYPE = 415,
+ PJSIP_SC_UNSUPPORTED_URI_SCHEME = 416,
+ PJSIP_SC_BAD_EXTENSION = 420,
+ PJSIP_SC_EXTENSION_REQUIRED = 421,
+ PJSIP_SC_SESSION_TIMER_TOO_SMALL = 422,
+ PJSIP_SC_INTERVAL_TOO_BRIEF = 423,
+ PJSIP_SC_TEMPORARILY_UNAVAILABLE = 480,
+ PJSIP_SC_CALL_TSX_DOES_NOT_EXIST = 481,
+ PJSIP_SC_LOOP_DETECTED = 482,
+ PJSIP_SC_TOO_MANY_HOPS = 483,
+ PJSIP_SC_ADDRESS_INCOMPLETE = 484,
+ PJSIP_AC_AMBIGUOUS = 485,
+ PJSIP_SC_BUSY_HERE = 486,
+ PJSIP_SC_REQUEST_TERMINATED = 487,
+ PJSIP_SC_NOT_ACCEPTABLE_HERE = 488,
+ PJSIP_SC_BAD_EVENT = 489,
+ PJSIP_SC_REQUEST_UPDATED = 490,
+ PJSIP_SC_REQUEST_PENDING = 491,
+ PJSIP_SC_UNDECIPHERABLE = 493,
+
+ PJSIP_SC_INTERNAL_SERVER_ERROR = 500,
+ PJSIP_SC_NOT_IMPLEMENTED = 501,
+ PJSIP_SC_BAD_GATEWAY = 502,
+ PJSIP_SC_SERVICE_UNAVAILABLE = 503,
+ PJSIP_SC_SERVER_TIMEOUT = 504,
+ PJSIP_SC_VERSION_NOT_SUPPORTED = 505,
+ PJSIP_SC_MESSAGE_TOO_LARGE = 513,
+ PJSIP_SC_PRECONDITION_FAILURE = 580,
+
+ PJSIP_SC_BUSY_EVERYWHERE = 600,
+ PJSIP_SC_DECLINE = 603,
+ PJSIP_SC_DOES_NOT_EXIST_ANYWHERE = 604,
+ PJSIP_SC_NOT_ACCEPTABLE_ANYWHERE = 606,
+
+ PJSIP_SC_TSX_TIMEOUT = PJSIP_SC_REQUEST_TIMEOUT,
+ /*PJSIP_SC_TSX_RESOLVE_ERROR = 702,*/
+ PJSIP_SC_TSX_TRANSPORT_ERROR = PJSIP_SC_SERVICE_UNAVAILABLE,
+
+ /* This is not an actual status code, but rather a constant
+ * to force GCC to use 32bit to represent this enum, since
+ * we have a code in PJSUA-LIB that assigns an integer
+ * to this enum (see pjsua_acc_get_info() function).
+ */
+ PJSIP_SC__force_32bit = 0x7FFFFFFF
+
+} pjsip_status_code;
+
+/**
+ * Get the default status text for the status code.
+ *
+ * @param status_code SIP Status Code
+ *
+ * @return textual message for the status code.
+ */
+PJ_DECL(const pj_str_t*) pjsip_get_status_text(int status_code);
+
+/**
+ * This macro returns non-zero (TRUE) if the specified status_code is
+ * in the same class as the code_class.
+ *
+ * @param status_code The status code.
+ * @param code_class The status code in the class (for example 100, 200).
+ */
+#define PJSIP_IS_STATUS_IN_CLASS(status_code, code_class) \
+ (status_code/100 == code_class/100)
+
+/**
+ * @}
+ */
+
+/* **************************************************************************/
+/**
+ * @addtogroup PJSIP_MSG_MEDIA Media/MIME Type
+ * @brief Media/MIME type declaration and manipulations.
+ * @ingroup PJSIP_MSG
+ * @{
+ */
+
+/**
+ * This structure describes SIP media type, as used for example in
+ * Accept and Content-Type header..
+ */
+typedef struct pjsip_media_type
+{
+ pj_str_t type; /**< Media type. */
+ pj_str_t subtype; /**< Media subtype. */
+ pjsip_param param; /**< Media type parameters */
+} pjsip_media_type;
+
+
+/**
+ * Initialize the media type with the specified type and subtype string.
+ *
+ * @param mt The media type.
+ * @param type Optionally specify the media type.
+ * @param subtype Optionally specify the media subtype.
+ */
+PJ_DECL(void) pjsip_media_type_init(pjsip_media_type *mt,
+ pj_str_t *type,
+ pj_str_t *subtype);
+
+/**
+ * Initialize the media type with the specified type and subtype string.
+ *
+ * @param mt The media type.
+ * @param type Optionally specify the media type.
+ * @param subtype Optionally specify the media subtype.
+ */
+PJ_DECL(void) pjsip_media_type_init2(pjsip_media_type *mt,
+ char *type,
+ char *subtype);
+
+/**
+ * Compare two media types.
+ *
+ * @param mt1 The first media type.
+ * @param mt2 The second media type.
+ * @param cmp_param Specify how to compare the media type parameters:
+ * - 0: do not compare parameters
+ * - 1: compare parameters but ignore parameters that
+ * only appear in one of the media type.
+ * - 2: compare the parameters.
+ *
+ * @return Zero if both media types are equal, -1 if mt1 < mt2,
+ * 1 if mt1 > mt2.
+ */
+PJ_DECL(int) pjsip_media_type_cmp(const pjsip_media_type *mt1,
+ const pjsip_media_type *mt2,
+ int cmp_param);
+
+/**
+ * Copy SIP media type to another.
+ *
+ * @param pool Pool to duplicate strings.
+ * @param dst Destination structure.
+ * @param src Source structure.
+ */
+PJ_DECL(void) pjsip_media_type_cp(pj_pool_t *pool,
+ pjsip_media_type *dst,
+ const pjsip_media_type *src);
+
+/**
+ * Print media type to the specified buffer.
+ *
+ * @param buf Destination buffer.
+ * @param len Length of the buffer.
+ * @param mt The media type to be printed.
+ *
+ * @return The number of characters printed to the buffer, or -1
+ * if there's not enough space in the buffer.
+ */
+PJ_DECL(int) pjsip_media_type_print(char *buf, unsigned len,
+ const pjsip_media_type *mt);
+
+/**
+ * @}
+ */
+
+/* **************************************************************************/
+/**
+ * @addtogroup PJSIP_MSG_BODY Message Body
+ * @brief SIP message body structures and manipulation.
+ * @ingroup PJSIP_MSG
+ * @{
+ */
+
+/**
+ * Generic abstraction to message body.
+ * When an incoming message is parsed (pjsip_parse_msg()), the parser fills in
+ * all members with the appropriate value. The 'data' and 'len' member will
+ * describe portion of incoming packet which denotes the message body.
+ * When application needs to attach message body to outgoing SIP message, it
+ * must fill in all members of this structure.
+ */
+struct pjsip_msg_body
+{
+ /** MIME content type.
+ * For incoming messages, the parser will fill in this member with the
+ * content type found in Content-Type header.
+ *
+ * For outgoing messages, application may fill in this member with
+ * appropriate value, because the stack will generate Content-Type header
+ * based on the value specified here.
+ *
+ * If the content_type is empty, no Content-Type AND Content-Length header
+ * will be added to the message. The stack assumes that application adds
+ * these headers themselves.
+ */
+ pjsip_media_type content_type;
+
+ /** Pointer to buffer which holds the message body data.
+ * For incoming messages, the parser will fill in this member with the
+ * pointer to the body string.
+ *
+ * When sending outgoing message, this member doesn't need to point to the
+ * actual message body string. It can be assigned with arbitrary pointer,
+ * because the value will only need to be understood by the print_body()
+ * function. The stack itself will not try to interpret this value, but
+ * instead will always call the print_body() whenever it needs to get the
+ * actual body string.
+ */
+ void *data;
+
+ /** The length of the data.
+ * For incoming messages, the parser will fill in this member with the
+ * actual length of message body.
+ *
+ * When sending outgoing message, again just like the "data" member, the
+ * "len" member doesn't need to point to the actual length of the body
+ * string.
+ */
+ unsigned len;
+
+ /** Pointer to function to print this message body.
+ * Application must set a proper function here when sending outgoing
+ * message.
+ *
+ * @param msg_body This structure itself.
+ * @param buf The buffer.
+ * @param size The buffer size.
+ *
+ * @return The length of the string printed, or -1 if there is
+ * not enough space in the buffer to print the whole
+ * message body.
+ */
+ int (*print_body)(struct pjsip_msg_body *msg_body,
+ char *buf, pj_size_t size);
+
+ /** Clone the data part only of this message body. Note that this only
+ * duplicates the data part of the body instead of the whole message
+ * body. If application wants to duplicate the entire message body
+ * structure, it must call #pjsip_msg_body_clone().
+ *
+ * @param pool Pool used to clone the data.
+ * @param data The data inside message body, to be cloned.
+ * @param len The length of the data.
+ *
+ * @return New data duplicated from the original data.
+ */
+ void* (*clone_data)(pj_pool_t *pool, const void *data, unsigned len);
+
+};
+
+/**
+ * General purpose function to textual data in a SIP body. Attach this function
+ * in a SIP message body only if the data in pjsip_msg_body is a textual
+ * message ready to be embedded in a SIP message. If the data in the message
+ * body is not a textual body, then application must supply a custom function
+ * to print that body.
+ *
+ * @param msg_body The message body.
+ * @param buf Buffer to copy the message body to.
+ * @param size The size of the buffer.
+ *
+ * @return The length copied to the buffer, or -1.
+ */
+PJ_DECL(int) pjsip_print_text_body( pjsip_msg_body *msg_body,
+ char *buf, pj_size_t size);
+
+/**
+ * General purpose function to clone textual data in a SIP body. Attach this
+ * function as "clone_data" member of the SIP body only if the data type
+ * is a text (i.e. C string, not pj_str_t), and the length indicates the
+ * length of the text.
+ *
+ * @param pool Pool used to clone the data.
+ * @param data Textual data.
+ * @param len The length of the string.
+ *
+ * @return New text duplicated from the original text.
+ */
+PJ_DECL(void*) pjsip_clone_text_data( pj_pool_t *pool, const void *data,
+ unsigned len);
+
+
+/**
+ * Clone the message body in src_body to the dst_body. This will duplicate
+ * the contents of the message body using the \a clone_data member of the
+ * source message body.
+ *
+ * @param pool Pool to use to duplicate the message body.
+ * @param dst_body Destination message body.
+ * @param src_body Source message body to duplicate.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_msg_body_copy( pj_pool_t *pool,
+ pjsip_msg_body *dst_body,
+ const pjsip_msg_body *src_body );
+
+
+/**
+ * Create cloned message body. This will duplicate the contents of the message
+ * body using the \a clone_data member of the source message body.
+ *
+ * @param pool Pool to use to duplicate the message body.
+ * @param body Source message body to duplicate.
+ *
+ * @return The cloned message body on successfull.
+ */
+PJ_DECL(pjsip_msg_body*) pjsip_msg_body_clone( pj_pool_t *pool,
+ const pjsip_msg_body *body );
+
+
+/**
+ * Create a text message body. Use this function to create message body when
+ * the content is a simple text. For non-text message body (e.g.
+ * pjmedia_sdp_session or pj_xml_node), application must construct the message
+ * manually.
+ *
+ * @param pool Pool to allocate message body and its contents.
+ * @param type MIME type (e.g. "text").
+ * @param subtype MIME subtype (e.g. "plain").
+ * @param text The text content to be put in the message body.
+ *
+ * @return A new message body with the specified Content-Type and
+ * text.
+ */
+PJ_DECL(pjsip_msg_body*) pjsip_msg_body_create( pj_pool_t *pool,
+ const pj_str_t *type,
+ const pj_str_t *subtype,
+ const pj_str_t *text );
+
+/**
+ * @}
+ */
+
+/* **************************************************************************/
+/**
+ * @defgroup PJSIP_MSG_MSG Message Structure
+ * @brief SIP message (request and response) structure and operations.
+ * @ingroup PJSIP_MSG
+ * @{
+ */
+
+/**
+ * Message type (request or response).
+ */
+typedef enum pjsip_msg_type_e
+{
+ PJSIP_REQUEST_MSG, /**< Indicates request message. */
+ PJSIP_RESPONSE_MSG /**< Indicates response message. */
+} pjsip_msg_type_e;
+
+
+/**
+ * This structure describes a SIP message.
+ */
+struct pjsip_msg
+{
+ /** Message type (ie request or response). */
+ pjsip_msg_type_e type;
+
+ /** The first line of the message can be either request line for request
+ * messages, or status line for response messages. It is represented here
+ * as a union.
+ */
+ union
+ {
+ /** Request Line. */
+ struct pjsip_request_line req;
+
+ /** Status Line. */
+ struct pjsip_status_line status;
+ } line;
+
+ /** List of message headers. */
+ pjsip_hdr hdr;
+
+ /** Pointer to message body, or NULL if no message body is attached to
+ * this mesage.
+ */
+ pjsip_msg_body *body;
+};
+
+
+/**
+ * Create new request or response message.
+ *
+ * @param pool The pool.
+ * @param type Message type.
+ * @return New message, or THROW exception if failed.
+ */
+PJ_DECL(pjsip_msg*) pjsip_msg_create( pj_pool_t *pool, pjsip_msg_type_e type);
+
+
+/**
+ * Perform a deep clone of a SIP message.
+ *
+ * @param pool The pool for creating the new message.
+ * @param msg The message to be duplicated.
+ *
+ * @return New message, which is duplicated from the original
+ * message.
+ */
+PJ_DECL(pjsip_msg*) pjsip_msg_clone( pj_pool_t *pool, const pjsip_msg *msg);
+
+
+/**
+ * Find a header in the message by the header type.
+ *
+ * @param msg The message.
+ * @param type The header type to find.
+ * @param start The first header field where the search should begin.
+ * If NULL is specified, then the search will begin from the
+ * first header, otherwise the search will begin at the
+ * specified header.
+ *
+ * @return The header field, or NULL if no header with the specified
+ * type is found.
+ */
+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.
+ *
+ * @param msg The message.
+ * @param name The header name to find.
+ * @param start The first header field where the search should begin.
+ * If NULL is specified, then the search will begin from the
+ * first header, otherwise the search will begin at the
+ * specified header.
+ *
+ * @return The header field, or NULL if no header with the specified
+ * type is found.
+ */
+PJ_DECL(void*) pjsip_msg_find_hdr_by_name( const pjsip_msg *msg,
+ const pj_str_t *name,
+ const void *start);
+
+/**
+ * Find a header in the message by its name and short name version.
+ *
+ * @param msg The message.
+ * @param name The header name to find.
+ * @param sname The short name version of the header name.
+ * @param start The first header field where the search should begin.
+ * If NULL is specified, then the search will begin from the
+ * first header, otherwise the search will begin at the
+ * specified header.
+ *
+ * @return The header field, or NULL if no header with the specified
+ * type is found.
+ */
+PJ_DECL(void*) pjsip_msg_find_hdr_by_names(const pjsip_msg *msg,
+ const pj_str_t *name,
+ const pj_str_t *sname,
+ const void *start);
+
+/**
+ * Find and remove a header in the message.
+ *
+ * @param msg The message.
+ * @param hdr The header type to find.
+ * @param start The first header field where the search should begin,
+ * or NULL to search from the first header in the message.
+ *
+ * @return The header field, or NULL if not found.
+ */
+PJ_DECL(void*) pjsip_msg_find_remove_hdr( pjsip_msg *msg,
+ pjsip_hdr_e hdr, void *start);
+
+/**
+ * Add a header to the message, putting it last in the header list.
+ *
+ * @param msg The message.
+ * @param hdr The header to add.
+ *
+ * @bug Once the header is put in a list (or message), it can not be put in
+ * other list (or message). Otherwise Real Bad Thing will happen.
+ */
+PJ_INLINE(void) pjsip_msg_add_hdr( pjsip_msg *msg, pjsip_hdr *hdr )
+{
+ pj_list_insert_before(&msg->hdr, hdr);
+}
+
+/**
+ * Add header field to the message, putting it in the front of the header list.
+ *
+ * @param msg The message.
+ * @param hdr The header to add.
+ *
+ * @bug Once the header is put in a list (or message), it can not be put in
+ * other list (or message). Otherwise Real Bad Thing will happen.
+ */
+PJ_INLINE(void) pjsip_msg_insert_first_hdr( pjsip_msg *msg, pjsip_hdr *hdr )
+{
+ pj_list_insert_after(&msg->hdr, hdr);
+}
+
+/**
+ * Print the message to the specified buffer.
+ *
+ * @param msg The message to print.
+ * @param buf The buffer
+ * @param size The size of the buffer.
+ *
+ * @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(const pjsip_msg *msg,
+ char *buf, pj_size_t size);
+
+
+/*
+ * Some usefull macros to find common headers.
+ */
+
+
+/**
+ * Find Call-ID header.
+ *
+ * @param msg The message.
+ * @return Call-ID header instance.
+ */
+#define PJSIP_MSG_CID_HDR(msg) \
+ ((pjsip_cid_hdr*)pjsip_msg_find_hdr(msg, PJSIP_H_CALL_ID, NULL))
+
+/**
+ * Find CSeq header.
+ *
+ * @param msg The message.
+ * @return CSeq header instance.
+ */
+#define PJSIP_MSG_CSEQ_HDR(msg) \
+ ((pjsip_cseq_hdr*)pjsip_msg_find_hdr(msg, PJSIP_H_CSEQ, NULL))
+
+/**
+ * Find From header.
+ *
+ * @param msg The message.
+ * @return From header instance.
+ */
+#define PJSIP_MSG_FROM_HDR(msg) \
+ ((pjsip_from_hdr*)pjsip_msg_find_hdr(msg, PJSIP_H_FROM, NULL))
+
+/**
+ * Find To header.
+ *
+ * @param msg The message.
+ * @return To header instance.
+ */
+#define PJSIP_MSG_TO_HDR(msg) \
+ ((pjsip_to_hdr*)pjsip_msg_find_hdr(msg, PJSIP_H_TO, NULL))
+
+
+/**
+ * @}
+ */
+
+/* **************************************************************************/
+/**
+ * @addtogroup PJSIP_MSG_HDR
+ * @{
+ */
+
+/**
+ * Generic SIP header, which contains hname and a string hvalue.
+ * Note that this header is not supposed to be used as 'base' class for headers.
+ */
+typedef struct pjsip_generic_string_hdr
+{
+ /** Standard header field. */
+ PJSIP_DECL_HDR_MEMBER(struct pjsip_generic_string_hdr);
+ /** hvalue */
+ pj_str_t hvalue;
+} pjsip_generic_string_hdr;
+
+
+/**
+ * Create a new instance of generic header. A generic header can have an
+ * arbitrary header name.
+ *
+ * @param pool The pool.
+ * @param hname The header name to be assigned to the header, or NULL to
+ * assign the header name with some string.
+ * @param hvalue Optional string to be assigned as the value.
+ *
+ * @return The header, or THROW exception.
+ */
+PJ_DECL(pjsip_generic_string_hdr*)
+pjsip_generic_string_hdr_create( pj_pool_t *pool,
+ const pj_str_t *hname,
+ const pj_str_t *hvalue);
+
+
+/**
+ * Initialize a preallocated memory with the header structure. This function
+ * should only be called when application uses its own memory allocation to
+ * allocate memory block for the specified header (e.g. in C++, when the
+ * header is allocated with "new" operator).
+ * For normal applications, they should use pjsip_xxx_hdr_create() instead,
+ * which allocates memory and initialize it in one go.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ * @param hname The header name to be assigned to the header, or NULL to
+ * assign the header name with some string later.
+ * @param hvalue Optional string to be assigned as the value.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_generic_string_hdr*)
+pjsip_generic_string_hdr_init( pj_pool_t *pool,
+ void *mem,
+ const pj_str_t *hname,
+ const pj_str_t *hvalue);
+
+
+/**
+ * Construct a generic string header without allocating memory from the pool.
+ * This function is useful to create a temporary header which life-time is
+ * very short (for example, creating the header in the stack to be passed
+ * as argument to a function which will copy the header).
+ *
+ * @param h The header to be initialized.
+ * @param hname The header name to be assigned to the header, or NULL to
+ * assign the header name with some string.
+ * @param hvalue Optional string to be assigned as the value.
+ *
+ * @return The header, or THROW exception.
+ */
+PJ_DECL(void) pjsip_generic_string_hdr_init2(pjsip_generic_string_hdr *h,
+ pj_str_t *hname,
+ pj_str_t *hvalue);
+
+
+/* **************************************************************************/
+
+/**
+ * Generic SIP header, which contains hname and a string hvalue.
+ */
+typedef struct pjsip_generic_int_hdr
+{
+ PJSIP_DECL_HDR_MEMBER(struct pjsip_generic_int_hdr); /**< Standard header field. */
+ pj_int32_t ivalue; /**< ivalue */
+} pjsip_generic_int_hdr;
+
+
+/**
+ * Create a new instance of generic header. A generic header can have an
+ * arbitrary header name.
+ *
+ * @param pool The pool.
+ * @param hname The header name to be assigned to the header, or NULL to
+ * assign the header name with some string.
+ * @param hvalue The value to be assigned to the header.
+ *
+ * @return The header, or THROW exception.
+ */
+PJ_DECL(pjsip_generic_int_hdr*) pjsip_generic_int_hdr_create( pj_pool_t *pool,
+ const pj_str_t *hname,
+ int hvalue );
+
+
+/**
+ * Initialize a preallocated memory with the header structure. This function
+ * should only be called when application uses its own memory allocation to
+ * allocate memory block for the specified header (e.g. in C++, when the
+ * header is allocated with "new" operator).
+ * For normal applications, they should use pjsip_xxx_hdr_create() instead,
+ * which allocates memory and initialize it in one go.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ * @param hname The header name to be assigned to the header, or NULL to
+ * assign the header name with some string later.
+ * @param value Value to be assigned to the header.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_generic_int_hdr*) pjsip_generic_int_hdr_init( pj_pool_t *pool,
+ void *mem,
+ const pj_str_t *hname,
+ int value );
+
+/* **************************************************************************/
+
+/** Maximum elements in the header array. */
+#define PJSIP_GENERIC_ARRAY_MAX_COUNT 32
+
+/**
+ * Generic array of string header.
+ */
+typedef struct pjsip_generic_array_hdr
+{
+ /** Standard header fields. */
+ PJSIP_DECL_HDR_MEMBER(struct pjsip_generic_array_hdr);
+
+ /** Number of tags/elements. */
+ unsigned count;
+
+ /** Tags/elements. */
+ pj_str_t values[PJSIP_GENERIC_ARRAY_MAX_COUNT];
+
+} pjsip_generic_array_hdr;
+
+/**
+ * Create generic array header.
+ *
+ * @param pool Pool to allocate memory from.
+ * @param hname Header name.
+ *
+ * @return New generic array header.
+ */
+PJ_DECL(pjsip_generic_array_hdr*) pjsip_generic_array_hdr_create(pj_pool_t *pool,
+ const pj_str_t *hname);
+
+/**
+ * Initialize a preallocated memory with the header structure. This function
+ * should only be called when application uses its own memory allocation to
+ * allocate memory block for the specified header (e.g. in C++, when the
+ * header is allocated with "new" operator).
+ * For normal applications, they should use pjsip_xxx_hdr_create() instead,
+ * which allocates memory and initialize it in one go.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ * @param hname The header name to be assigned to the header, or NULL to
+ * assign the header name with some string later.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_generic_array_hdr*) pjsip_generic_array_hdr_init(pj_pool_t *pool,
+ void *mem,
+ const pj_str_t *hname);
+
+
+/* **************************************************************************/
+
+/** Accept header. */
+typedef pjsip_generic_array_hdr pjsip_accept_hdr;
+
+/** Maximum fields in Accept header. */
+#define PJSIP_MAX_ACCEPT_COUNT PJSIP_GENERIC_ARRAY_MAX_COUNT
+
+/**
+ * Create new Accept header instance.
+ *
+ * @param pool The pool.
+ *
+ * @return New Accept header instance.
+ */
+PJ_DECL(pjsip_accept_hdr*) pjsip_accept_hdr_create(pj_pool_t *pool);
+
+/**
+ * Initialize a preallocated memory with the header structure. This function
+ * should only be called when application uses its own memory allocation to
+ * allocate memory block for the specified header (e.g. in C++, when the
+ * header is allocated with "new" operator).
+ * For normal applications, they should use pjsip_xxx_hdr_create() instead,
+ * which allocates memory and initialize it in one go.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_accept_hdr*) pjsip_accept_hdr_init( pj_pool_t *pool,
+ void *mem );
+
+
+/* **************************************************************************/
+
+/**
+ * Allow header.
+ */
+typedef pjsip_generic_array_hdr pjsip_allow_hdr;
+
+/**
+ * Create new Allow header instance.
+ *
+ * @param pool The pool.
+ *
+ * @return New Allow header instance.
+ */
+PJ_DECL(pjsip_allow_hdr*) pjsip_allow_hdr_create(pj_pool_t *pool);
+
+
+
+/**
+ * Initialize a preallocated memory with the header structure. This function
+ * should only be called when application uses its own memory allocation to
+ * allocate memory block for the specified header (e.g. in C++, when the
+ * header is allocated with "new" operator).
+ * For normal applications, they should use pjsip_xxx_hdr_create() instead,
+ * which allocates memory and initialize it in one go.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_allow_hdr*) pjsip_allow_hdr_init( pj_pool_t *pool,
+ void *mem );
+
+/* **************************************************************************/
+
+/**
+ * Call-ID header.
+ */
+typedef struct pjsip_cid_hdr
+{
+ PJSIP_DECL_HDR_MEMBER(struct pjsip_cid_hdr);
+ pj_str_t id; /**< Call-ID string. */
+} pjsip_cid_hdr;
+
+
+/**
+ * Create new Call-ID header.
+ *
+ * @param pool The pool.
+ *
+ * @return new Call-ID header.
+ */
+PJ_DECL(pjsip_cid_hdr*) pjsip_cid_hdr_create( pj_pool_t *pool );
+
+
+/**
+ * Initialize a preallocated memory with the header structure. This function
+ * should only be called when application uses its own memory allocation to
+ * allocate memory block for the specified header (e.g. in C++, when the
+ * header is allocated with "new" operator).
+ * For normal applications, they should use pjsip_xxx_hdr_create() instead,
+ * which allocates memory and initialize it in one go.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_cid_hdr*) pjsip_cid_hdr_init( pj_pool_t *pool,
+ void *mem );
+
+
+
+/* **************************************************************************/
+/**
+ * Content-Length header.
+ */
+typedef struct pjsip_clen_hdr
+{
+ PJSIP_DECL_HDR_MEMBER(struct pjsip_clen_hdr);
+ int len; /**< Content length. */
+} pjsip_clen_hdr;
+
+/**
+ * Create new Content-Length header.
+ *
+ * @param pool the pool.
+ * @return A new Content-Length header instance.
+ */
+PJ_DECL(pjsip_clen_hdr*) pjsip_clen_hdr_create( pj_pool_t *pool );
+
+/**
+ * Initialize a preallocated memory with the header structure. This function
+ * should only be called when application uses its own memory allocation to
+ * allocate memory block for the specified header (e.g. in C++, when the
+ * header is allocated with "new" operator).
+ * For normal applications, they should use pjsip_xxx_hdr_create() instead,
+ * which allocates memory and initialize it in one go.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_clen_hdr*) pjsip_clen_hdr_init( pj_pool_t *pool,
+ void *mem );
+
+
+/* **************************************************************************/
+/**
+ * CSeq header.
+ */
+typedef struct pjsip_cseq_hdr
+{
+ PJSIP_DECL_HDR_MEMBER(struct pjsip_cseq_hdr);
+ pj_int32_t cseq; /**< CSeq number. */
+ pjsip_method method; /**< CSeq method. */
+} pjsip_cseq_hdr;
+
+
+/** Create new CSeq header.
+ *
+ * @param pool The pool.
+ * @return A new CSeq header instance.
+ */
+PJ_DECL(pjsip_cseq_hdr*) pjsip_cseq_hdr_create( pj_pool_t *pool );
+
+/**
+ * Initialize a preallocated memory with the header structure. This function
+ * should only be called when application uses its own memory allocation to
+ * allocate memory block for the specified header (e.g. in C++, when the
+ * header is allocated with "new" operator).
+ * For normal applications, they should use pjsip_xxx_hdr_create() instead,
+ * which allocates memory and initialize it in one go.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_cseq_hdr*) pjsip_cseq_hdr_init( pj_pool_t *pool,
+ void *mem );
+
+/* **************************************************************************/
+/**
+ * Contact header.
+ * In this library, contact header only contains single URI. If a message has
+ * multiple URI in the Contact header, the URI will be put in separate Contact
+ * headers.
+ */
+typedef struct pjsip_contact_hdr
+{
+ PJSIP_DECL_HDR_MEMBER(struct pjsip_contact_hdr);
+ int star; /**< The contact contains only a '*' character */
+ pjsip_uri *uri; /**< URI in the contact. */
+ int q1000; /**< The "q" value times 1000 (to avoid float) */
+ pj_int32_t expires; /**< Expires parameter, otherwise -1 if not present. */
+ pjsip_param other_param; /**< Other parameters, concatenated in a single string. */
+} pjsip_contact_hdr;
+
+
+/**
+ * Create a new Contact header.
+ *
+ * @param pool The pool.
+ * @return A new instance of Contact header.
+ */
+PJ_DECL(pjsip_contact_hdr*) pjsip_contact_hdr_create( pj_pool_t *pool );
+
+/**
+ * Initialize a preallocated memory with the header structure. This function
+ * should only be called when application uses its own memory allocation to
+ * allocate memory block for the specified header (e.g. in C++, when the
+ * header is allocated with "new" operator).
+ * For normal applications, they should use pjsip_xxx_hdr_create() instead,
+ * which allocates memory and initialize it in one go.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_contact_hdr*) pjsip_contact_hdr_init( pj_pool_t *pool,
+ void *mem );
+
+
+/* **************************************************************************/
+/**
+ * Content-Type.
+ */
+typedef struct pjsip_ctype_hdr
+{
+ PJSIP_DECL_HDR_MEMBER(struct pjsip_ctype_hdr);
+ pjsip_media_type media; /**< Media type. */
+} pjsip_ctype_hdr;
+
+
+/**
+ * Create a nwe Content Type header.
+ *
+ * @param pool The pool.
+ * @return A new Content-Type header.
+ */
+PJ_DECL(pjsip_ctype_hdr*) pjsip_ctype_hdr_create( pj_pool_t *pool );
+
+/**
+ * Initialize a preallocated memory with the header structure. This function
+ * should only be called when application uses its own memory allocation to
+ * allocate memory block for the specified header (e.g. in C++, when the
+ * header is allocated with "new" operator).
+ * For normal applications, they should use pjsip_xxx_hdr_create() instead,
+ * which allocates memory and initialize it in one go.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_ctype_hdr*) pjsip_ctype_hdr_init( pj_pool_t *pool,
+ void *mem );
+
+/* **************************************************************************/
+/** Expires header. */
+typedef pjsip_generic_int_hdr pjsip_expires_hdr;
+
+/**
+ * Create a new Expires header.
+ *
+ * @param pool The pool.
+ * @param value The expiration value.
+ *
+ * @return A new Expires header.
+ */
+PJ_DECL(pjsip_expires_hdr*) pjsip_expires_hdr_create( pj_pool_t *pool,
+ int value);
+
+/**
+ * Initialize a preallocated memory with the header structure. This function
+ * should only be called when application uses its own memory allocation to
+ * allocate memory block for the specified header (e.g. in C++, when the
+ * header is allocated with "new" operator).
+ * For normal applications, they should use pjsip_xxx_hdr_create() instead,
+ * which allocates memory and initialize it in one go.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ * @param value The expiration value.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_expires_hdr*) pjsip_expires_hdr_init( pj_pool_t *pool,
+ void *mem,
+ int value );
+
+
+
+/* **************************************************************************/
+/**
+ * To or From header.
+ */
+typedef struct pjsip_fromto_hdr
+{
+ PJSIP_DECL_HDR_MEMBER(struct pjsip_fromto_hdr);
+ pjsip_uri *uri; /**< URI in From/To header. */
+ pj_str_t tag; /**< Header "tag" parameter. */
+ pjsip_param other_param; /**< Other params, concatenated as a single string. */
+} pjsip_fromto_hdr;
+
+/** Alias for From header. */
+typedef pjsip_fromto_hdr pjsip_from_hdr;
+
+/** Alias for To header. */
+typedef pjsip_fromto_hdr pjsip_to_hdr;
+
+/**
+ * Create a From header.
+ *
+ * @param pool The pool.
+ * @return New instance of From header.
+ */
+PJ_DECL(pjsip_from_hdr*) pjsip_from_hdr_create( pj_pool_t *pool );
+
+/**
+ * Initialize a preallocated memory with the header structure. This function
+ * should only be called when application uses its own memory allocation to
+ * allocate memory block for the specified header (e.g. in C++, when the
+ * header is allocated with "new" operator).
+ * For normal applications, they should use pjsip_xxx_hdr_create() instead,
+ * which allocates memory and initialize it in one go.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_from_hdr*) pjsip_from_hdr_init( pj_pool_t *pool,
+ void *mem );
+
+/**
+ * Create a To header.
+ *
+ * @param pool The pool.
+ * @return New instance of To header.
+ */
+PJ_DECL(pjsip_to_hdr*) pjsip_to_hdr_create( pj_pool_t *pool );
+
+/**
+ * Initialize a preallocated memory with the header structure. This function
+ * should only be called when application uses its own memory allocation to
+ * allocate memory block for the specified header (e.g. in C++, when the
+ * header is allocated with "new" operator).
+ * For normal applications, they should use pjsip_xxx_hdr_create() instead,
+ * which allocates memory and initialize it in one go.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_to_hdr*) pjsip_to_hdr_init( pj_pool_t *pool,
+ void *mem );
+
+/**
+ * Convert the header to a From header.
+ *
+ * @param hdr The generic from/to header.
+ * @return "From" header.
+ */
+PJ_DECL(pjsip_from_hdr*) pjsip_fromto_hdr_set_from( pjsip_fromto_hdr *hdr );
+
+/**
+ * Convert the header to a To header.
+ *
+ * @param hdr The generic from/to header.
+ * @return "To" header.
+ */
+PJ_DECL(pjsip_to_hdr*) pjsip_fromto_hdr_set_to( pjsip_fromto_hdr *hdr );
+
+
+/* **************************************************************************/
+/**
+ * Max-Forwards header.
+ */
+typedef pjsip_generic_int_hdr pjsip_max_fwd_hdr;
+
+/**
+ * Create new Max-Forwards header instance.
+ *
+ * @param pool The pool.
+ * @param value The Max-Forwards value.
+ *
+ * @return New Max-Forwards header instance.
+ */
+PJ_DECL(pjsip_max_fwd_hdr*)
+pjsip_max_fwd_hdr_create(pj_pool_t *pool, int value);
+
+
+/**
+ * Initialize a preallocated memory with the header structure. This function
+ * should only be called when application uses its own memory allocation to
+ * allocate memory block for the specified header (e.g. in C++, when the
+ * header is allocated with "new" operator).
+ * For normal applications, they should use pjsip_xxx_hdr_create() instead,
+ * which allocates memory and initialize it in one go.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ * @param value The Max-Forwards value.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_max_fwd_hdr*)
+pjsip_max_fwd_hdr_init( pj_pool_t *pool, void *mem, int value );
+
+
+/* **************************************************************************/
+/**
+ * Min-Expires header.
+ */
+typedef pjsip_generic_int_hdr pjsip_min_expires_hdr;
+
+/**
+ * Create new Min-Expires header instance.
+ *
+ * @param pool The pool.
+ * @param value The Min-Expires value.
+ *
+ * @return New Min-Expires header instance.
+ */
+PJ_DECL(pjsip_min_expires_hdr*) pjsip_min_expires_hdr_create(pj_pool_t *pool,
+ int value);
+
+
+/**
+ * Initialize a preallocated memory with the header structure. This function
+ * should only be called when application uses its own memory allocation to
+ * allocate memory block for the specified header (e.g. in C++, when the
+ * header is allocated with "new" operator).
+ * For normal applications, they should use pjsip_xxx_hdr_create() instead,
+ * which allocates memory and initialize it in one go.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ * @param value The Min-Expires value.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_min_expires_hdr*) pjsip_min_expires_hdr_init( pj_pool_t *pool,
+ void *mem,
+ int value );
+
+
+/* **************************************************************************/
+/**
+ * Record-Route and Route headers.
+ */
+typedef struct pjsip_routing_hdr
+{
+ PJSIP_DECL_HDR_MEMBER(struct pjsip_routing_hdr); /**< Generic header fields. */
+ pjsip_name_addr name_addr; /**< The URL in the Route/Record-Route header. */
+ pjsip_param other_param; /**< Other parameter. */
+} pjsip_routing_hdr;
+
+/** Alias for Record-Route header. */
+typedef pjsip_routing_hdr pjsip_rr_hdr;
+
+/** Alias for Route header. */
+typedef pjsip_routing_hdr pjsip_route_hdr;
+
+
+/**
+ * Create new Record-Route header from the pool.
+ *
+ * @param pool The pool.
+ * @return A new instance of Record-Route header.
+ */
+PJ_DECL(pjsip_rr_hdr*) pjsip_rr_hdr_create( pj_pool_t *pool );
+
+/**
+ * Initialize a preallocated memory with the header structure. This function
+ * should only be called when application uses its own memory allocation to
+ * allocate memory block for the specified header (e.g. in C++, when the
+ * header is allocated with "new" operator).
+ * For normal applications, they should use pjsip_xxx_hdr_create() instead,
+ * which allocates memory and initialize it in one go.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_rr_hdr*) pjsip_rr_hdr_init( pj_pool_t *pool,
+ void *mem );
+
+/**
+ * Create new Route header from the pool.
+ *
+ * @param pool The pool.
+ * @return A new instance of "Route" header.
+ */
+PJ_DECL(pjsip_route_hdr*) pjsip_route_hdr_create( pj_pool_t *pool );
+
+/**
+ * Initialize a preallocated memory with the header structure. This function
+ * should only be called when application uses its own memory allocation to
+ * allocate memory block for the specified header (e.g. in C++, when the
+ * header is allocated with "new" operator).
+ * For normal applications, they should use pjsip_xxx_hdr_create() instead,
+ * which allocates memory and initialize it in one go.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_route_hdr*) pjsip_route_hdr_init( pj_pool_t *pool,
+ void *mem );
+
+/**
+ * Convert generic routing header to Record-Route header.
+ *
+ * @param r The generic routing header, or a "Routing" header.
+ * @return Record-Route header.
+ */
+PJ_DECL(pjsip_rr_hdr*) pjsip_routing_hdr_set_rr( pjsip_routing_hdr *r );
+
+/**
+ * Convert generic routing header to "Route" header.
+ *
+ * @param r The generic routing header, or a "Record-Route" header.
+ * @return "Route" header.
+ */
+PJ_DECL(pjsip_route_hdr*) pjsip_routing_hdr_set_route( pjsip_routing_hdr *r );
+
+/* **************************************************************************/
+/**
+ * Require header.
+ */
+typedef pjsip_generic_array_hdr pjsip_require_hdr;
+
+/**
+ * Create new Require header instance.
+ *
+ * @param pool The pool.
+ *
+ * @return New Require header instance.
+ */
+PJ_DECL(pjsip_require_hdr*) pjsip_require_hdr_create(pj_pool_t *pool);
+
+/**
+ * Initialize a preallocated memory with the header structure. This function
+ * should only be called when application uses its own memory allocation to
+ * allocate memory block for the specified header (e.g. in C++, when the
+ * header is allocated with "new" operator).
+ * For normal applications, they should use pjsip_xxx_hdr_create() instead,
+ * which allocates memory and initialize it in one go.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_require_hdr*) pjsip_require_hdr_init( pj_pool_t *pool,
+ void *mem );
+
+
+/* **************************************************************************/
+/**
+ * Retry-After header.
+ */
+typedef struct pjsip_retry_after_hdr
+{
+ /** Standard header field. */
+ PJSIP_DECL_HDR_MEMBER(struct pjsip_retry_after_hdr);
+ pj_int32_t ivalue; /**< Retry-After value */
+ pjsip_param param; /**< Optional parameters */
+ pj_str_t comment; /**< Optional comments. */
+} pjsip_retry_after_hdr;
+
+
+/**
+ * Create new Retry-After header instance.
+ *
+ * @param pool The pool.
+ * @param value The Retry-After value.
+ *
+ * @return New Retry-After header instance.
+ */
+PJ_DECL(pjsip_retry_after_hdr*) pjsip_retry_after_hdr_create(pj_pool_t *pool,
+ int value);
+
+/**
+ * Initialize a preallocated memory with the header structure.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ * @param value The Retry-After value.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_retry_after_hdr*) pjsip_retry_after_hdr_init( pj_pool_t *pool,
+ void *mem,
+ int value );
+
+
+/* **************************************************************************/
+/**
+ * Supported header.
+ */
+typedef pjsip_generic_array_hdr pjsip_supported_hdr;
+
+/**
+ * Create new Supported header instance.
+ *
+ * @param pool The pool.
+ *
+ * @return New Supported header instance.
+ */
+PJ_DECL(pjsip_supported_hdr*) pjsip_supported_hdr_create(pj_pool_t *pool);
+
+/**
+ * Initialize a preallocated memory with the header structure.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_supported_hdr*) pjsip_supported_hdr_init( pj_pool_t *pool,
+ void *mem );
+
+/* **************************************************************************/
+/**
+ * Unsupported header.
+ */
+typedef pjsip_generic_array_hdr pjsip_unsupported_hdr;
+
+/**
+ * Create new Unsupported header instance.
+ *
+ * @param pool The pool.
+ *
+ * @return New Unsupported header instance.
+ */
+PJ_DECL(pjsip_unsupported_hdr*) pjsip_unsupported_hdr_create(pj_pool_t *pool);
+
+/**
+ * Initialize a preallocated memory with the header structure.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_unsupported_hdr*) pjsip_unsupported_hdr_init( pj_pool_t *pool,
+ void *mem );
+
+/* **************************************************************************/
+/**
+ * SIP Via header.
+ * In this implementation, Via header can only have one element in each header.
+ * If a message arrives with multiple elements in a single Via, then they will
+ * be split up into multiple Via headers.
+ */
+typedef struct pjsip_via_hdr
+{
+ PJSIP_DECL_HDR_MEMBER(struct pjsip_via_hdr);
+ pj_str_t transport; /**< Transport type. */
+ pjsip_host_port sent_by; /**< Host and optional port */
+ int ttl_param; /**< TTL parameter, or -1 if it's not specified. */
+ int rport_param; /**< "rport" parameter, 0 to specify without
+ port number, -1 means doesn't exist. */
+ pj_str_t maddr_param; /**< "maddr" parameter. */
+ pj_str_t recvd_param; /**< "received" parameter. */
+ pj_str_t branch_param; /**< "branch" parameter. */
+ pjsip_param other_param; /**< Other parameters, concatenated as single string. */
+ pj_str_t comment; /**< Comment. */
+} pjsip_via_hdr;
+
+/**
+ * Create a new Via header.
+ *
+ * @param pool The pool.
+ * @return A new "Via" header instance.
+ */
+PJ_DECL(pjsip_via_hdr*) pjsip_via_hdr_create( pj_pool_t *pool );
+
+/**
+ * Initialize a preallocated memory with the header structure.
+ *
+ * @param pool Pool for additional memory allocation if required.
+ * @param mem Pre-allocated memory to be initialized as the header.
+ *
+ * @return The header instance, which points to the same memory
+ * location as the mem argument.
+ */
+PJ_DECL(pjsip_via_hdr*) pjsip_via_hdr_init( pj_pool_t *pool,
+ void *mem );
+
+/* **************************************************************************/
+/**
+ * SIP Warning header.
+ * In this version, Warning header is just a typedef for generic string
+ * header.
+ */
+typedef pjsip_generic_string_hdr pjsip_warning_hdr;
+
+/**
+ * Create a warning header with the specified contents.
+ *
+ * @param pool Pool to allocate memory from.
+ * @param code Warning code, 300-399.
+ * @param host The host portion of the Warning header.
+ * @param text The warning text, which MUST not be quoted with
+ * double quote.
+ *
+ * @return The Warning header field.
+ */
+PJ_DECL(pjsip_warning_hdr*) pjsip_warning_hdr_create( pj_pool_t *pool,
+ int code,
+ const pj_str_t *host,
+ const pj_str_t *text);
+
+/**
+ * Create a warning header and initialize the contents from the error
+ * message for the specified status code. The warning code will be
+ * set to 399.
+ *
+ * @param pool Pool to allocate memory from.
+ * @param host The host portion of the Warning header.
+ * @param status The error status code, which error text will be
+ * put in as the Warning text.
+ *
+ * @return The Warning header field.
+ */
+PJ_DECL(pjsip_warning_hdr*)
+pjsip_warning_hdr_create_from_status( pj_pool_t *pool,
+ const pj_str_t *host,
+ pj_status_t status);
+
+/* **************************************************************************/
+/** Accept-Encoding header. */
+typedef pjsip_generic_string_hdr pjsip_accept_encoding_hdr;
+
+/** Create Accept-Encoding header. */
+#define pjsip_accept_encoding_hdr_create pjsip_generic_string_hdr_create
+
+/** Accept-Language header. */
+typedef pjsip_generic_string_hdr pjsip_accept_lang_hdr;
+
+/** Create Accept-Language header. */
+#define pjsip_accept_lang_hdr_create pjsip_generic_string_hdr_create
+
+/** Alert-Info header. */
+typedef pjsip_generic_string_hdr pjsip_alert_info_hdr;
+
+/** Create Alert-Info header. */
+#define pjsip_alert_info_hdr_create pjsip_generic_string_hdr_create
+
+/** Authentication-Info header. */
+typedef pjsip_generic_string_hdr pjsip_auth_info_hdr;
+
+/** Create Authentication-Info header. */
+#define pjsip_auth_info_hdr_create pjsip_generic_string_hdr_create
+
+/** Call-Info header. */
+typedef pjsip_generic_string_hdr pjsip_call_info_hdr;
+
+/** Create Call-Info header. */
+#define pjsip_call_info_hdr_create pjsip_generic_string_hdr_create
+
+/** Content-Disposition header. */
+typedef pjsip_generic_string_hdr pjsip_content_disposition_hdr;
+
+/** Create Content-Disposition header. */
+#define pjsip_content_disposition_hdr_create pjsip_generic_string_hdr_create
+
+/** Content-Encoding header. */
+typedef pjsip_generic_string_hdr pjsip_content_encoding_hdr;
+
+/** Create Content-Encoding header. */
+#define pjsip_content_encoding_hdr_create pjsip_generic_string_hdr_create
+
+/** Content-Language header. */
+typedef pjsip_generic_string_hdr pjsip_content_lang_hdr;
+
+/** Create Content-Language header. */
+#define pjsip_content_lang_hdr_create pjsip_generic_string_hdr_create
+
+/** Date header. */
+typedef pjsip_generic_string_hdr pjsip_date_hdr;
+
+/** Create Date header. */
+#define pjsip_date_hdr_create pjsip_generic_string_hdr_create
+
+/** Error-Info header. */
+typedef pjsip_generic_string_hdr pjsip_err_info_hdr;
+
+/** Create Error-Info header. */
+#define pjsip_err_info_hdr_create pjsip_generic_string_hdr_create
+
+/** In-Reply-To header. */
+typedef pjsip_generic_string_hdr pjsip_in_reply_to_hdr;
+
+/** Create In-Reply-To header. */
+#define pjsip_in_reply_to_hdr_create pjsip_generic_string_hdr_create
+
+/** MIME-Version header. */
+typedef pjsip_generic_string_hdr pjsip_mime_version_hdr;
+
+/** Create MIME-Version header. */
+#define pjsip_mime_version_hdr_create pjsip_generic_string_hdr_create
+
+/** Organization header. */
+typedef pjsip_generic_string_hdr pjsip_organization_hdr;
+
+/** Create Organization header. */
+#define pjsip_organization_hdr_create pjsip_genric_string_hdr_create
+
+/** Priority header. */
+typedef pjsip_generic_string_hdr pjsip_priority_hdr;
+
+/** Create Priority header. */
+#define pjsip_priority_hdr_create pjsip_generic_string_hdr_create
+
+/** Proxy-Require header. */
+typedef pjsip_generic_string_hdr pjsip_proxy_require_hdr;
+
+/** Reply-To header. */
+typedef pjsip_generic_string_hdr pjsip_reply_to_hdr;
+
+/** Create Reply-To header. */
+#define pjsip_reply_to_hdr_create pjsip_generic_string_hdr_create
+
+/** Server header. */
+typedef pjsip_generic_string_hdr pjsip_server_hdr;
+
+/** Create Server header. */
+#define pjsip_server_hdr_create pjsip_generic_string_hdr_create
+
+/** Subject header. */
+typedef pjsip_generic_string_hdr pjsip_subject_hdr;
+
+/** Create Subject header. */
+#define pjsip_subject_hdr_create pjsip_generic_string_hdr_create
+
+/** Timestamp header. */
+typedef pjsip_generic_string_hdr pjsip_timestamp_hdr;
+
+/** Create Timestamp header. */
+#define pjsip_timestamp_hdr_create pjsip_generic_string_hdr_create
+
+/** User-Agent header. */
+typedef pjsip_generic_string_hdr pjsip_user_agent_hdr;
+
+/** Create User-Agent header. */
+#define pjsip_user_agent_hdr_create pjsip_generic_string_hdr_create
+
+
+/**
+ * @}
+ */
+
+/**
+ * @} PJSIP_MSG
+ */
+
+
+PJ_END_DECL
+
+#endif /* __PJSIP_SIP_MSG_H__ */
+
diff --git a/pjsip/include/pjsip/sip_multipart.h b/pjsip/include/pjsip/sip_multipart.h
new file mode 100644
index 0000000..be8ae26
--- /dev/null
+++ b/pjsip/include/pjsip/sip_multipart.h
@@ -0,0 +1,179 @@
+/* $Id: sip_multipart.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * 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_MULTIPART_H__
+#define __PJSIP_SIP_MULTIPART_H__
+
+/**
+ * @file pjsip/sip_multipart.h
+ * @brief Multipart support.
+ */
+
+#include <pjsip/sip_msg.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJSIP_MULTIPART Multipart message bodies.
+ * @ingroup PJSIP_MSG
+ * @brief Support for multipart message bodies.
+ * @{
+ */
+
+/**
+ * This structure describes the individual body part inside a multipart
+ * message body. It mainly contains the message body itself and optional
+ * headers.
+ */
+typedef struct pjsip_multipart_part
+{
+ /**
+ * Standard list element.
+ */
+ PJ_DECL_LIST_MEMBER(struct pjsip_multipart_part);
+
+ /**
+ * Optional message headers.
+ */
+ pjsip_hdr hdr;
+
+ /**
+ * Pointer to the message body.
+ */
+ pjsip_msg_body *body;
+
+} pjsip_multipart_part;
+
+/**
+ * Create an empty multipart body.
+ *
+ * @param pool Memory pool to allocate memory from.
+ * @param ctype Optional MIME media type of the multipart
+ * bodies. If not specified, "multipart/mixed"
+ * will be used.
+ * @param boundary Optional string to be set as part boundary.
+ * The boundary string excludes the leading
+ * hyphens. If this parameter is NULL or empty,
+ * a random boundary will be generated.
+ *
+ * @return Multipart body instance with no part.
+ */
+PJ_DECL(pjsip_msg_body*) pjsip_multipart_create(pj_pool_t *pool,
+ const pjsip_media_type *ctype,
+ const pj_str_t *boundary);
+
+/**
+ * Create an empty multipart part.
+ *
+ * @param pool The memory pool.
+ *
+ * @return The multipart part.
+ */
+PJ_DECL(pjsip_multipart_part*) pjsip_multipart_create_part(pj_pool_t *pool);
+
+
+/**
+ * Perform a deep clone to a multipart part.
+ *
+ * @param pool The memory pool.
+ * @param part The part to be duplicated.
+ *
+ * @return Copy of the multipart part.
+ */
+PJ_DECL(pjsip_multipart_part*)
+pjsip_multipart_clone_part(pj_pool_t *pool,
+ const pjsip_multipart_part *part);
+
+/**
+ * Add a part into multipart bodies.
+ *
+ * @param pool The memory pool.
+ * @param mp The multipart bodies.
+ * @param part The part to be added into the bodies.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_multipart_add_part(pj_pool_t *pool,
+ pjsip_msg_body *mp,
+ pjsip_multipart_part *part);
+
+/**
+ * Get the first part of multipart bodies.
+ *
+ * @param mp The multipart bodies.
+ *
+ * @return The first part, or NULL if the multipart
+ * bodies currently doesn't hold any elements.
+ */
+PJ_DECL(pjsip_multipart_part*)
+pjsip_multipart_get_first_part(const pjsip_msg_body *mp);
+
+/**
+ * Get the next part after the specified part.
+ *
+ * @param mp The multipart bodies.
+ * @param part The part.
+ *
+ * @return The next part, or NULL if there is no other part after
+ * the part.
+ */
+PJ_DECL(pjsip_multipart_part*)
+pjsip_multipart_get_next_part(const pjsip_msg_body *mp,
+ pjsip_multipart_part *part);
+
+/**
+ * Find a body inside multipart bodies which has the specified content type.
+ *
+ * @param mp The multipart body.
+ * @param content_type Content type to find.
+ * @param start If specified, the search will begin at
+ * start->next. Otherwise it will begin at
+ * the first part in the multipart bodies.
+ *
+ * @return The first part with the specified content type
+ * if found, or NULL.
+ */
+PJ_DECL(pjsip_multipart_part*)
+pjsip_multipart_find_part( const pjsip_msg_body *mp,
+ const pjsip_media_type *content_type,
+ const pjsip_multipart_part *start);
+
+/**
+ * Parse multipart message.
+ *
+ * @param pool Memory pool.
+ * @param buf Input buffer.
+ * @param len The buffer length.
+ * @param ctype Content type of the multipart body.
+ * @param options Parsing options, must be zero for now.
+ *
+ * @return Multipart message body.
+ */
+PJ_DECL(pjsip_msg_body*) pjsip_multipart_parse(pj_pool_t *pool,
+ char *buf, pj_size_t len,
+ const pjsip_media_type *ctype,
+ unsigned options);
+
+/**
+ * @} PJSIP_MULTIPART
+ */
+
+
+PJ_END_DECL
+
+#endif /* __PJSIP_SIP_MULTIPART_H__ */
diff --git a/pjsip/include/pjsip/sip_parser.h b/pjsip/include/pjsip/sip_parser.h
new file mode 100644
index 0000000..bc341d0
--- /dev/null
+++ b/pjsip/include/pjsip/sip_parser.h
@@ -0,0 +1,416 @@
+/* $Id: sip_parser.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * 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_PARSER_H__
+#define __PJSIP_SIP_PARSER_H__
+
+/**
+ * @file sip_parser.h
+ * @brief SIP Message Parser
+ */
+
+#include <pjsip/sip_msg.h>
+#include <pjlib-util/scanner.h>
+#include <pj/list.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJSIP_PARSER Parser
+ * @ingroup PJSIP_MSG
+ * @brief Message and message elements parsing.
+ * @{
+ */
+
+/**
+ * URI Parsing options.
+ */
+enum
+{
+ /** If this option is specified, function #pjsip_parse_uri will return
+ * the URI object as pjsip_name_addr instead of the corresponding
+ * URI object.
+ */
+ PJSIP_PARSE_URI_AS_NAMEADDR = 1,
+
+ /** If this option is specified, function #pjsip_parse_uri and other
+ * internal functions that this function calls will parse URI according
+ * to convention for parsing From/To/Contact header. For example, when
+ * the URI is not enclosed in brackets ("<" and ">"), all parameters
+ * are treated as header parameters (not URI parameters).
+ */
+ PJSIP_PARSE_URI_IN_FROM_TO_HDR = 2
+};
+
+/**
+ * Parser syntax error exception value.
+ */
+extern int PJSIP_SYN_ERR_EXCEPTION;
+
+/**
+ * This structure is used to get error reporting from parser.
+ */
+typedef struct pjsip_parser_err_report
+{
+ /** Standard header fields. */
+ PJ_DECL_LIST_MEMBER(struct pjsip_parser_err_report);
+ int except_code; /**< Error exception (e.g. PJSIP_SYN_ERR_EXCEPTION) */
+ int line; /**< Line number. */
+ int col; /**< Column number. */
+ pj_str_t hname; /**< Header name, if any. */
+} pjsip_parser_err_report;
+
+
+/**
+ * Parsing context, the default argument for parsing functions.
+ */
+typedef struct pjsip_parse_ctx
+{
+ pj_scanner *scanner; /**< The scanner. */
+ pj_pool_t *pool; /**< The pool. */
+ pjsip_rx_data *rdata; /**< Optional rdata. */
+} pjsip_parse_ctx;
+
+
+/**
+ * Type of function to parse header. The parsing function must follow these
+ * specification:
+ * - It must not modify the input text.
+ * - The hname and HCOLON has been parsed prior to invoking the handler.
+ * - It returns the header instance on success.
+ * - For error reporting, it must throw PJSIP_SYN_ERR_EXCEPTION exception
+ * instead of just returning NULL.
+ * When exception is thrown, the return value is ignored.
+ * - It must read the header separator after finished reading the header
+ * body. The separator types are described below, and if they don't exist,
+ * exception must be thrown. Header separator can be a:
+ * - newline, such as when the header is part of a SIP message.
+ * - ampersand, such as when the header is part of an URI.
+ * - for the last header, these separator is optional since parsing
+ * can be terminated when seeing EOF.
+ */
+typedef pjsip_hdr* (pjsip_parse_hdr_func)(pjsip_parse_ctx *context);
+
+/**
+ * Type of function to parse URI scheme.
+ * Most of the specification of header parser handler (pjsip_parse_hdr_func)
+ * also applies here (except the separator part).
+ */
+typedef void* (pjsip_parse_uri_func)(pj_scanner *scanner, pj_pool_t *pool,
+ pj_bool_t parse_params);
+
+/**
+ * Register header parser handler. The parser handler MUST follow the
+ * specification of header parser handler function. New registration
+ * overwrites previous registration with the same name.
+ *
+ * @param hname The header name.
+ * @param hshortname The short header name or NULL.
+ * @param fptr The pointer to function to parser the header.
+ *
+ * @return PJ_SUCCESS if success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_register_hdr_parser( const char *hname,
+ const char *hshortname,
+ pjsip_parse_hdr_func *fptr);
+
+/**
+ * Unregister previously registered header parser handler.
+ * All the arguments MUST exactly equal to the value specified upon
+ * registration of the handler.
+ *
+ * @param hname The header name registered.
+ * @param hshortname The short header name registered, or NULL.
+ * @param fptr Previously registered function to parse the header.
+ *
+ * @return zero if unregistration was successfull.
+ */
+PJ_DECL(pj_status_t) pjsip_unregister_hdr_parser( const char *hname,
+ const char *hshortname,
+ pjsip_parse_hdr_func *fptr);
+
+/**
+ * Register URI scheme parser handler.
+ *
+ * @param scheme The URI scheme registered.
+ * @param func The URI parser function.
+ *
+ * @return zero on success.
+ */
+PJ_DECL(pj_status_t) pjsip_register_uri_parser( char *scheme,
+ pjsip_parse_uri_func *func);
+
+/**
+ * Unregister URI scheme parser handler.
+ * All the arguments MUST exactly equal to the value specified upon
+ * registration of the handler.
+ *
+ * @param scheme The URI scheme as registered previously.
+ * @param func The function handler as registered previously.
+ *
+ * @return zero if the registration was successfull.
+ */
+PJ_DECL(pj_status_t) pjsip_unregister_uri_parser( const char *scheme,
+ pjsip_parse_uri_func *func);
+
+/**
+ * Parse an URI in the input and return the correct instance of URI.
+ *
+ * @param pool The pool to get memory allocations.
+ * @param buf The input buffer, which MUST be NULL terminated.
+ * @param size The length of the string (not counting NULL terminator).
+ * @param options If no options are given (value is zero), the object
+ * returned is dependent on the syntax of the URI,
+ * eg. basic SIP URL, TEL URL, or name address.
+ * If option PJSIP_PARSE_URI_AS_NAMEADDR is given,
+ * then the returned object is always name address object,
+ * with the relevant URI object contained in the name
+ * address object.
+ * @return The URI or NULL when failed. No exception is thrown by
+ * this function (or any public parser functions).
+ */
+PJ_DECL(pjsip_uri*) pjsip_parse_uri( pj_pool_t *pool,
+ char *buf, pj_size_t size,
+ unsigned options);
+
+/**
+ * Parse SIP status line.
+ *
+ * @param buf Text buffer to parse, which MUST be NULL terminated.
+ * @param size The size of the buffer, excluding the NULL character.
+ * @param status_line Structure to receive the parsed elements.
+ *
+ * @return PJ_SUCCESS if a status line is parsed successfully.
+ */
+PJ_DECL(pj_status_t) pjsip_parse_status_line(char *buf, pj_size_t size,
+ pjsip_status_line *status_line);
+
+
+/**
+ * Parse a packet buffer and build a full SIP message from the packet. This
+ * function parses all parts of the message, including request/status line,
+ * all headers, and the message body. The message body however is only
+ * treated as a text block, ie. the function will not try to parse the content
+ * of the body.
+ *
+ * @param pool The pool to allocate memory.
+ * @param buf The input buffer, which MUST be NULL terminated.
+ * @param size The length of the string (not counting NULL terminator).
+ * @param err_list If this parameter is not NULL, then the parser will
+ * put error messages during parsing in this list.
+ *
+ * @return The message or NULL when failed. No exception is thrown
+ * by this function (or any public parser functions).
+ */
+PJ_DECL(pjsip_msg *) pjsip_parse_msg( pj_pool_t *pool,
+ char *buf, pj_size_t size,
+ pjsip_parser_err_report *err_list);
+
+
+/**
+ * Parse a packet buffer and build a rdata. The resulting message will be
+ * stored in \c msg field in the \c rdata. This behaves pretty much like
+ * #pjsip_parse_msg(), except that it will also initialize the header fields
+ * in the \c rdata.
+ *
+ * This function is normally called by the transport layer.
+ *
+ * @param buf The input buffer, which MUST be NULL terminated.
+ * @param size The length of the string (not counting NULL terminator).
+ * @param rdata The receive data buffer to store the message and
+ * its elements.
+ *
+ * @return The message inside the rdata if successfull, or NULL.
+ */
+PJ_DECL(pjsip_msg *) pjsip_parse_rdata( char *buf, pj_size_t size,
+ pjsip_rx_data *rdata );
+
+/**
+ * Check incoming packet to see if a (probably) valid SIP message has been
+ * received.
+ *
+ * @param buf The input buffer, which must be NULL terminated.
+ * @param size The buffer size.
+ * @param is_datagram Put non-zero if transport is datagram oriented.
+ * @param msg_size [out] If message is valid, this parameter will contain
+ * the size of the SIP message (including body, if any).
+ *
+ * @return PJ_SUCCESS if a message is found, or an error code.
+ */
+PJ_DECL(pj_status_t) pjsip_find_msg(const char *buf,
+ pj_size_t size,
+ pj_bool_t is_datagram,
+ pj_size_t *msg_size);
+
+/**
+ * Parse the content of a header and return the header instance.
+ * This function parses the content of a header (ie. part after colon) according
+ * to the expected name, and will return the correct instance of header.
+ *
+ * @param pool Pool to allocate memory for the header.
+ * @param hname Header name which is used to find the correct function
+ * to parse the header.
+ * @param line Header content, which must be NULL terminated.
+ * @param size The length of the string (not counting NULL terminator,
+ * if any).
+ * @param parsed_len If the value is not NULL, then upon return the function
+ * will fill the pointer with the length of the string
+ * that has been parsed. This is usefull for two purposes,
+ * one is when the string may contain more than one header
+ * lines, and two when an error happen the value can
+ * pinpoint the location of the error in the buffer.
+ *
+ * @return The instance of the header if parsing was successful,
+ * or otherwise a NULL pointer will be returned.
+ */
+PJ_DECL(void*) pjsip_parse_hdr( pj_pool_t *pool, const pj_str_t *hname,
+ char *line, pj_size_t size,
+ int *parsed_len);
+
+/**
+ * Parse header line(s). Multiple headers can be parsed by this function.
+ * When there are multiple headers, the headers MUST be separated by either
+ * a newline (as in SIP message) or ampersand mark (as in URI). This separator
+ * is optional for the last header.
+ *
+ * @param pool The pool.
+ * @param input The input text to parse, which must be NULL terminated.
+ * @param size The text length.
+ * @param hlist The header list to store the parsed headers.
+ * This list must have been initialized before calling
+ * this function.
+ * @param options Specify 1 here to make parsing stop when error is
+ * encountered when parsing the header. Otherwise the
+ * error is silently ignored and parsing resumes to the
+ * next line.
+ * @return zero if successfull, or -1 if error is encountered.
+ * Upon error, the \a hlist argument MAY contain
+ * successfully parsed headers.
+ */
+PJ_DECL(pj_status_t) pjsip_parse_headers( pj_pool_t *pool, char *input,
+ pj_size_t size, pjsip_hdr *hlist,
+ unsigned options);
+
+
+/**
+ * @}
+ */
+
+
+#ifdef _MSC_VER
+# pragma warning(push)
+# pragma warning(disable:4510) // default constructor could not be generated
+# pragma warning(disable:4512) // assignment operator could not be generated
+# pragma warning(disable:4610) // user defined constructor required
+#endif
+
+/**
+ * Parser constants. @see pjsip_parser_const()
+ */
+typedef struct pjsip_parser_const_t
+{
+ const pj_str_t pjsip_USER_STR; /**< "user" string constant. */
+ const pj_str_t pjsip_METHOD_STR; /**< "method" string constant */
+ const pj_str_t pjsip_TRANSPORT_STR; /**< "transport" string const. */
+ const pj_str_t pjsip_MADDR_STR; /**< "maddr" string const. */
+ const pj_str_t pjsip_LR_STR; /**< "lr" string const. */
+ const pj_str_t pjsip_SIP_STR; /**< "sip" string constant. */
+ const pj_str_t pjsip_SIPS_STR; /**< "sips" string constant. */
+ const pj_str_t pjsip_TEL_STR; /**< "tel" string constant. */
+ const pj_str_t pjsip_BRANCH_STR; /**< "branch" string constant. */
+ const pj_str_t pjsip_TTL_STR; /**< "ttl" string constant. */
+ const pj_str_t pjsip_RECEIVED_STR; /**< "received" string const. */
+ const pj_str_t pjsip_Q_STR; /**< "q" string constant. */
+ const pj_str_t pjsip_EXPIRES_STR; /**< "expires" string constant. */
+ const pj_str_t pjsip_TAG_STR; /**< "tag" string constant. */
+ const pj_str_t pjsip_RPORT_STR; /**< "rport" string const. */
+
+ pj_cis_t pjsip_HOST_SPEC; /**< For scanning host part. */
+ pj_cis_t pjsip_DIGIT_SPEC; /**< Decimal digits */
+ pj_cis_t pjsip_ALPHA_SPEC; /**< Alpha (A-Z, a-z) */
+ pj_cis_t pjsip_ALNUM_SPEC; /**< Decimal + Alpha. */
+ pj_cis_t pjsip_TOKEN_SPEC; /**< Token. */
+ pj_cis_t pjsip_TOKEN_SPEC_ESC; /**< Token without '%' character */
+ pj_cis_t pjsip_VIA_PARAM_SPEC; /**< Via param is token + ":" for
+ IPv6. */
+ pj_cis_t pjsip_VIA_PARAM_SPEC_ESC; /**< .. as above without '%' */
+ pj_cis_t pjsip_HEX_SPEC; /**< Hexadecimal digits. */
+ pj_cis_t pjsip_PARAM_CHAR_SPEC; /**< For scanning pname (or pvalue
+ when it's not quoted.) in URI */
+ pj_cis_t pjsip_PARAM_CHAR_SPEC_ESC; /**< Variant without the escape ('%')
+ char */
+ pj_cis_t pjsip_HDR_CHAR_SPEC; /**< Chars in hname/havalue in URL. */
+ pj_cis_t pjsip_HDR_CHAR_SPEC_ESC; /**< Variant without the escape ('%')
+ char */
+ pj_cis_t pjsip_PROBE_USER_HOST_SPEC;/**< Hostname characters. */
+ pj_cis_t pjsip_PASSWD_SPEC; /**< Password. */
+ pj_cis_t pjsip_PASSWD_SPEC_ESC; /**< Variant without the escape ('%')
+ char */
+ pj_cis_t pjsip_USER_SPEC; /**< User */
+ pj_cis_t pjsip_USER_SPEC_ESC; /**< Variant without the escape ('%')
+ char */
+ pj_cis_t pjsip_USER_SPEC_LENIENT; /**< User, with additional '#' char */
+ pj_cis_t pjsip_USER_SPEC_LENIENT_ESC;/**< pjsip_USER_SPEC_ESC with '#' */
+ pj_cis_t pjsip_NOT_NEWLINE; /**< For eating up header, basically
+ any chars except newlines or
+ zero. */
+ pj_cis_t pjsip_NOT_COMMA_OR_NEWLINE;/**< Array elements. */
+ pj_cis_t pjsip_DISPLAY_SPEC; /**< Used when searching for display
+ name. */
+ pj_cis_t pjsip_OTHER_URI_CONTENT; /**< Generic URI content. */
+
+} pjsip_parser_const_t;
+
+#ifdef _MSC_VER
+# pragma warning(pop)
+#endif
+
+
+/**
+ * Get parser constants.
+ */
+PJ_DECL(const pjsip_parser_const_t*) pjsip_parser_const(void);
+
+
+/*
+ * Parser utilities.
+ */
+enum
+{
+ PJSIP_PARSE_REMOVE_QUOTE = 1
+};
+
+/* Parse parameter in header (matching the character as token) */
+PJ_DECL(void) pjsip_parse_param_imp(pj_scanner *scanner, pj_pool_t *pool,
+ pj_str_t *pname, pj_str_t *pvalue,
+ unsigned opt);
+/* Parse parameter in URL (matching the character as paramchar) */
+PJ_DECL(void) pjsip_parse_uri_param_imp(pj_scanner *scanner, pj_pool_t *pool,
+ pj_str_t *pname, pj_str_t *pvalue,
+ unsigned opt);
+PJ_DECL(void) pjsip_concat_param_imp(pj_str_t *param, pj_pool_t *pool,
+ const pj_str_t *pname,
+ const pj_str_t *pvalue,
+ int sepchar);
+PJ_DECL(void) pjsip_parse_end_hdr_imp ( pj_scanner *scanner );
+
+PJ_END_DECL
+
+#endif /* __PJSIP_SIP_PARSER_H__ */
+
diff --git a/pjsip/include/pjsip/sip_private.h b/pjsip/include/pjsip/sip_private.h
new file mode 100644
index 0000000..e139fa6
--- /dev/null
+++ b/pjsip/include/pjsip/sip_private.h
@@ -0,0 +1,32 @@
+/* $Id: sip_private.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * 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_PRIVATE_H__
+#define __PJSIP_SIP_PRIVATE_H__
+
+/**
+ * @file sip_private.h
+ * @brief Private structures and functions for PJSIP Library.
+ */
+
+#include <pjsip/sip_types.h>
+
+
+#endif /* __PJSIP_PRIVATE_I_H__ */
+
diff --git a/pjsip/include/pjsip/sip_resolve.h b/pjsip/include/pjsip/sip_resolve.h
new file mode 100644
index 0000000..6f578a1
--- /dev/null
+++ b/pjsip/include/pjsip/sip_resolve.h
@@ -0,0 +1,291 @@
+/* $Id: sip_resolve.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * 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_RESOLVE_H__
+#define __PJSIP_SIP_RESOLVE_H__
+
+/**
+ * @file sip_resolve.h
+ * @brief
+ * This module contains the mechanism to resolve server address as specified by
+ * RFC 3263 - Locating SIP Servers
+ */
+
+#include <pjsip/sip_types.h>
+#include <pjlib-util/resolver.h>
+#include <pj/sock.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJSIP_RESOLVE SIP SRV Server Resolution (RFC 3263 - Locating SIP Servers)
+ * @ingroup PJSIP_TRANSPORT
+ * @brief Framework to resolve SIP servers based on RFC 3263.
+ * @{
+ * \section PJSIP_RESOLVE_FEATURES Features
+ *
+ * This is the SIP server resolution framework, which is modelled after
+ * RFC 3263 - Locating SIP Servers document. The SIP server resolution
+ * framework is asynchronous; callback will be called once the server
+ * address has been resolved (successfully or with errors).
+ *
+ * \subsection PJSIP_RESOLVE_CONFORMANT Conformance to RFC 3263
+ *
+ * The SIP server resolution framework is modelled after RFC 3263 (Locating
+ * SIP Servers) document, and it provides a single function (#pjsip_resolve())
+ * to resolve a domain into actual IP addresses of the servers, by querying
+ * DNS SRV record and DNS A record where necessary.
+ *
+ * The #pjsip_resolve() function performs the server resolution according
+ * to RFC 3263 with some additional fallback mechanisms, as follows:
+ * - if the target name is an IP address, the callback will be called
+ * immediately with the IP address. If port number was specified, this
+ * port number will be used, otherwise the default port number for the
+ * transport will be used (5060 for TCP/UDP, 5061 for TLS) if the transport
+ * is specified. If the transport is not specified, UDP with port number
+ * 5060 will be used.
+ * - if target name is not an IP address but it contains port number,
+ * then the target name is resolved with DNS A (or AAAA, when IPv6 is
+ * supported in the future) query, and the port is taken from the
+ * port number argument. The callback will be called once the DNS A
+ * resolution completes. If the DNS A resolution returns multiple IP
+ * addresses, these IP addresses will be returned to the caller.
+ * - if target name is not an IP address and port number is not specified,
+ * DNS SRV resolution will be performed for the specified name and
+ * transport type (or UDP when transport is not specified),
+ * then followed by DNS A (or AAAA, when IPv6 is supported)
+ * resolution for each target in the SRV record. If DNS SRV
+ * resolution returns error, DNS A (or AAAA) resolution will be
+ * performed for the original target (it is assumed that the target domain
+ * does not support SRV records). Upon successful completion,
+ * application callback will be called with each IP address of the
+ * target selected based on the load-balancing and fail-over criteria
+ * below.
+ *
+ * The above server resolution procedure differs from RFC 3263 in these
+ * regards:
+ * - currently #pjsip_resolve() doesn't support DNS NAPTR record.
+ * - if transport is not specified, it is assumed to be UDP (the proper
+ * behavior is to query the NAPTR record, but we don't support this
+ * yet).
+ *
+ *
+ * \subsection PJSIP_SIP_RESOLVE_FAILOVER_LOADBALANCE Load-Balancing and Fail-Over
+ *
+ * When multiple targets are returned in the DNS SRV response, server entries
+ * are selected based on the following rule (which is described in RFC 2782):
+ * - targets will be sorted based on the priority first.
+ * - for targets with the same priority, #pjsip_resolve() will select
+ * only one target according to its weight. To select this one target,
+ * the function associates running-sum for all targets, and generates
+ * a random number between zero and the total running-sum (inclusive).
+ * The target selected is the first target with running-sum greater than
+ * or equal to this random number.
+ *
+ * The above procedure will select one target for each priority, allowing
+ * application to fail-over to the next target when the previous target fails.
+ * These targets are returned in the #pjsip_server_addresses structure
+ * argument of the callback.
+ *
+ * \subsection PJSIP_SIP_RESOLVE_SIP_FEATURES SIP SRV Resolver Features
+ *
+ * Some features of the SIP resolver:
+ * - DNS SRV entries are returned on sorted order based on priority
+ * to allow failover to the next appropriate server.
+ * - The procedure in RFC 2782 is used to select server with the same
+ * priority to load-balance the servers load.
+ * - A single function (#pjsip_resolve()) performs all server resolution
+ * works, from resolving the SRV records to getting the actual IP addresses
+ * of the servers with DNS A (or AAAA) resolution.
+ * - When multiple DNS SRV records are returned, parallel DNS A (or AAAA)
+ * queries will be issued simultaneously.
+ * - The PJLIB-UTIL DNS resolver provides additional functionality such as
+ * response caching, query aggregation, parallel nameservers, fallback
+ * nameserver, etc., which will be described below.
+ *
+ *
+ * \subsection PJSIP_RESOLVE_DNS_FEATURES DNS Resolver Features
+ *
+ * The PJSIP server resolution framework uses PJLIB-UTIL DNS resolver engine
+ * for performing the asynchronous DNS request. The PJLIB-UTIL DNS resolver
+ * has some useful features, such as:
+ * - queries are asynchronous with configurable timeout,
+ * - query aggregation to combine multiple pending queries to the same
+ * DNS target into a single DNS request (to save message round-trip and
+ * processing),
+ * - response caching with TTL negotiated between the minimum TTL found in
+ * the response and the maximum TTL allowed in the configuration,
+ * - multiple nameservers, with active nameserver is selected from nameserver
+ * which provides the best response time,
+ * - fallback nameserver, with periodic detection of which name servers are
+ * active or down.
+ * - etc.
+ *
+ * Please consult PJLIB-UTIL DNS resolver documentation for more details.
+ *
+ *
+ * \section PJSIP_RESOLVE_USING Using the Resolver
+ *
+ * To maintain backward compatibility, the resolver MUST be enabled manually.
+ * With the default settings, the resolver WILL NOT perform DNS SRV resolution,
+ * as it will just resolve the name with standard pj_gethostbyname() function.
+ *
+ * Application can enable the SRV resolver by creating the PJLIB-UTIL DNS
+ * resolver with #pjsip_endpt_create_resolver(), configure the
+ * nameservers of the PJLIB-UTIL DNS resolver object by calling
+ * pj_dns_resolver_set_ns() function, and pass the DNS resolver object to
+ * #pjsip_resolver_set_resolver() function.
+ *
+ * Once the resolver is set, it will be used automatically by PJSIP everytime
+ * PJSIP needs to send SIP request/response messages.
+ *
+ *
+ * \section PJSIP_RESOLVE_REFERENCE Reference
+ *
+ * Reference:
+ * - RFC 2782: A DNS RR for specifying the location of services (DNS SRV)
+ * - RFC 3263: Locating SIP Servers
+ */
+
+/**
+ * The server addresses returned by the resolver.
+ */
+typedef struct pjsip_server_addresses
+{
+ /** Number of address records. */
+ unsigned count;
+
+ /** Address records. */
+ struct
+ {
+ /** Preferable transport to be used to contact this address. */
+ pjsip_transport_type_e type;
+
+ /** Server priority (the lower the higher the priority). */
+ unsigned priority;
+
+ /** Server weight (the higher the more load it can handle). */
+ unsigned weight;
+
+ /** The server's address. */
+ pj_sockaddr addr;
+
+ /** Address length. */
+ int addr_len;
+
+ } entry[PJSIP_MAX_RESOLVED_ADDRESSES];
+
+} pjsip_server_addresses;
+
+
+/**
+ * The type of callback function to be called when resolver finishes the job.
+ *
+ * @param status The status of the operation, which is zero on success.
+ * @param token The token that was associated with the job when application
+ * call the resolve function.
+ * @param addr The addresses resolved by the operation.
+ */
+typedef void pjsip_resolver_callback(pj_status_t status,
+ void *token,
+ const struct pjsip_server_addresses *addr);
+
+/**
+ * Create SIP resolver engine. Note that this function is normally called
+ * internally by pjsip_endpoint instance.
+ *
+ * @param pool Pool to allocate memory from.
+ * @param p_res Pointer to receive SIP resolver instance.
+ *
+ * @return PJ_SUCCESS when resolver can be successfully created.
+ */
+PJ_DECL(pj_status_t) pjsip_resolver_create(pj_pool_t *pool,
+ pjsip_resolver_t **p_res);
+
+/**
+ * Set the DNS resolver instance of the SIP resolver engine. Before the
+ * DNS resolver is set, the SIP resolver will use standard pj_gethostbyname()
+ * to resolve addresses.
+ *
+ * Note that application normally will use #pjsip_endpt_set_resolver() instead
+ * since it does not normally have access to the SIP resolver instance.
+ *
+ * @param res The SIP resolver engine.
+ * @param dns_res The DNS resolver instance to be used by the SIP resolver.
+ * This argument can be NULL to reset the internal DNS
+ * instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_resolver_set_resolver(pjsip_resolver_t *res,
+ pj_dns_resolver *dns_res);
+
+
+/**
+ * Get the DNS resolver instance of the SIP resolver engine.
+ *
+ * Note that application normally will use #pjsip_endpt_get_resolver() instead
+ * since it does not normally have access to the SIP resolver instance.
+ *
+ * @param res The SIP resolver engine.
+ *
+ * @return The DNS resolver instance (may be NULL)
+ */
+PJ_DECL(pj_dns_resolver*) pjsip_resolver_get_resolver(pjsip_resolver_t *res);
+
+/**
+ * Destroy resolver engine. Note that this will also destroy the internal
+ * DNS resolver inside the engine. If application doesn't want the internal
+ * DNS resolver to be destroyed, it should set the internal DNS resolver
+ * to NULL before calling this function.
+ *
+ * Note that this function will normally called by the SIP endpoint instance
+ * when the SIP endpoint instance is destroyed.
+ *
+ * @param resolver The resolver.
+ */
+PJ_DECL(void) pjsip_resolver_destroy(pjsip_resolver_t *resolver);
+
+/**
+ * Asynchronously resolve a SIP target host or domain according to rule
+ * specified in RFC 3263 (Locating SIP Servers). When the resolving operation
+ * has completed, the callback will be called.
+ *
+ * Note that application normally will use #pjsip_endpt_resolve() instead
+ * since it does not normally have access to the SIP resolver instance.
+ *
+ * @param resolver The resolver engine.
+ * @param pool The pool to allocate resolver job.
+ * @param target The target specification to be resolved.
+ * @param token A user defined token to be passed back to callback function.
+ * @param cb The callback function.
+ */
+PJ_DECL(void) pjsip_resolve( pjsip_resolver_t *resolver,
+ pj_pool_t *pool,
+ const pjsip_host_info *target,
+ void *token,
+ pjsip_resolver_callback *cb);
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+#endif /* __PJSIP_SIP_RESOLVE_H__ */
diff --git a/pjsip/include/pjsip/sip_tel_uri.h b/pjsip/include/pjsip/sip_tel_uri.h
new file mode 100644
index 0000000..f85ec74
--- /dev/null
+++ b/pjsip/include/pjsip/sip_tel_uri.h
@@ -0,0 +1,84 @@
+/* $Id: sip_tel_uri.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * 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_TEL_URI_H__
+#define __PJSIP_TEL_URI_H__
+
+/**
+ * @file sip_tel_uri.h
+ * @brief Tel: URI
+ */
+
+#include <pjsip/sip_uri.h>
+
+/**
+ * @addtogroup PJSIP_TEL_URI tel URI Scheme
+ * @ingroup PJSIP_URI
+ * @brief Support for "tel:" URI scheme.
+ * @{
+ */
+
+
+PJ_BEGIN_DECL
+
+/**
+ * tel: URI.
+ */
+typedef struct pjsip_tel_uri
+{
+ pjsip_uri_vptr *vptr; /**< Pointer to virtual function table. */
+ pj_str_t number; /**< Global or local phone number */
+ pj_str_t context; /**< Phone context (for local number). */
+ pj_str_t ext_param; /**< Extension param. */
+ pj_str_t isub_param; /**< ISDN sub-address param. */
+ pjsip_param other_param;/**< Other parameter. */
+} pjsip_tel_uri;
+
+
+/**
+ * Create a new tel: URI.
+ *
+ * @param pool The pool.
+ *
+ * @return New instance of tel: URI.
+ */
+PJ_DECL(pjsip_tel_uri*) pjsip_tel_uri_create(pj_pool_t *pool);
+
+/**
+ * This function compares two numbers for equality, according to rules as
+ * specified in RFC 3966.
+ *
+ * @param nb1 The first number.
+ * @param nb2 The second number.
+ *
+ * @return Zero if equal, -1 if nb1 is less than nb2, or +1 if
+ * nb1 is greater than nb2.
+ */
+PJ_DECL(int) pjsip_tel_nb_cmp(const pj_str_t *nb1, const pj_str_t *nb2);
+
+
+PJ_END_DECL
+
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJSIP_TEL_URI_H__ */
diff --git a/pjsip/include/pjsip/sip_transaction.h b/pjsip/include/pjsip/sip_transaction.h
new file mode 100644
index 0000000..1a75a7c
--- /dev/null
+++ b/pjsip/include/pjsip/sip_transaction.h
@@ -0,0 +1,414 @@
+/* $Id: sip_transaction.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * 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_mutex_t *mutex; /**< Mutex for this tsx. */
+ 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_uint32_t hashed_key; /**< Key's hashed value. */
+ 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.
+ *
+ * @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 );
+
+/**
+ * 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);
+
+/**
+ * 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 );
+
+
+/**
+ * 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.
+ */
+PJ_DECL(pj_status_t) pjsip_tsx_terminate( 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);
+
+
+/**
+ * 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__ */
+
diff --git a/pjsip/include/pjsip/sip_transport.h b/pjsip/include/pjsip/sip_transport.h
new file mode 100644
index 0000000..c8ea6fd
--- /dev/null
+++ b/pjsip/include/pjsip/sip_transport.h
@@ -0,0 +1,1406 @@
+/* $Id: sip_transport.h 4173 2012-06-20 10:39:05Z ming $ */
+/*
+ * 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);
+
+
+/*****************************************************************************
+ *
+ * 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.
+ *
+ * @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);
+
+/**
+ * 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__ */
+
diff --git a/pjsip/include/pjsip/sip_transport_loop.h b/pjsip/include/pjsip/sip_transport_loop.h
new file mode 100644
index 0000000..1883a02
--- /dev/null
+++ b/pjsip/include/pjsip/sip_transport_loop.h
@@ -0,0 +1,147 @@
+/* $Id: sip_transport_loop.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * 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_TRANSPORT_LOOP_H__
+#define __PJSIP_TRANSPORT_LOOP_H__
+
+
+/**
+ * @file sip_transport_loop.h
+ * @brief
+ * Loopback transport (for debugging)
+ */
+
+
+#include <pjsip/sip_transport.h>
+
+/**
+ * @defgroup PJSIP_TRANSPORT_LOOP Loop Transport
+ * @ingroup PJSIP_TRANSPORT
+ * @brief Loopback transport (for testing purposes).
+ * @{
+ * The loopback transport simply bounce back outgoing messages as
+ * incoming messages. This feature is used mostly during automated
+ * testing, to provide controlled behavior.
+ */
+
+PJ_BEGIN_DECL
+
+/**
+ * Create and start datagram loop transport.
+ *
+ * @param endpt The endpoint instance.
+ * @param transport Pointer to receive the transport instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_loop_start( pjsip_endpoint *endpt,
+ pjsip_transport **transport);
+
+
+/**
+ * Enable/disable flag to discard any packets sent using the specified
+ * loop transport.
+ *
+ * @param tp The loop transport.
+ * @param discard If non-zero, any outgoing packets will be discarded.
+ * @param prev_value Optional argument to receive previous value of
+ * the discard flag.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_loop_set_discard( pjsip_transport *tp,
+ pj_bool_t discard,
+ pj_bool_t *prev_value );
+
+
+/**
+ * Enable/disable flag to simulate network error. When this flag is set,
+ * outgoing transmission will return either immediate error or error via
+ * callback. If error is to be notified via callback, then the notification
+ * will occur after some delay, which is controlled by #pjsip_loop_set_delay().
+ *
+ * @param tp The loop transport.
+ * @param fail_flag If set to 1, the transport will return fail to deliver
+ * the message. If delay is zero, failure will occur
+ * immediately; otherwise it will be reported in callback.
+ * If set to zero, the transport will successfully deliver
+ * the packet.
+ * @param prev_value Optional argument to receive previous value of
+ * the failure flag.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_loop_set_failure( pjsip_transport *tp,
+ int fail_flag,
+ int *prev_value );
+
+
+/**
+ * Set delay (in miliseconds) before packet is received by the other end
+ * of the loop transport. This will also
+ * control the delay for error notification callback.
+ *
+ * @param tp The loop transport.
+ * @param delay Delay, in miliseconds.
+ * @param prev_value Optional argument to receive previous value of the
+ * delay.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_loop_set_recv_delay( pjsip_transport *tp,
+ unsigned delay,
+ unsigned *prev_value);
+
+
+/**
+ * Set delay (in miliseconds) before send notification is delivered to sender.
+ * This will also control the delay for error notification callback.
+ *
+ * @param tp The loop transport.
+ * @param delay Delay, in miliseconds.
+ * @param prev_value Optional argument to receive previous value of the
+ * delay.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_loop_set_send_callback_delay( pjsip_transport *tp,
+ unsigned delay,
+ unsigned *prev_value);
+
+
+/**
+ * Set both receive and send notification delay.
+ *
+ * @param tp The loop transport.
+ * @param delay Delay, in miliseconds.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_loop_set_delay( pjsip_transport *tp,
+ unsigned delay );
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJSIP_TRANSPORT_LOOP_H__ */
+
diff --git a/pjsip/include/pjsip/sip_transport_tcp.h b/pjsip/include/pjsip/sip_transport_tcp.h
new file mode 100644
index 0000000..285c6b6
--- /dev/null
+++ b/pjsip/include/pjsip/sip_transport_tcp.h
@@ -0,0 +1,210 @@
+/* $Id: sip_transport_tcp.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * 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_TRANSPORT_TCP_H__
+#define __PJSIP_TRANSPORT_TCP_H__
+
+/**
+ * @file sip_transport_tcp.h
+ * @brief SIP TCP Transport.
+ */
+
+#include <pjsip/sip_transport.h>
+#include <pj/sock_qos.h>
+
+
+/* Only declare the API if PJ_HAS_TCP is true */
+#if defined(PJ_HAS_TCP) && PJ_HAS_TCP!=0
+
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJSIP_TRANSPORT_TCP TCP Transport
+ * @ingroup PJSIP_TRANSPORT
+ * @brief API to create and register TCP transport.
+ * @{
+ * The functions below are used to create TCP transport and register
+ * the transport to the framework.
+ */
+
+/**
+ * Settings to be specified when creating the TCP transport. Application
+ * should initialize this structure with its default values by calling
+ * pjsip_tcp_transport_cfg_default().
+ */
+typedef struct pjsip_tcp_transport_cfg
+{
+ /**
+ * Address family to use. Valid values are pj_AF_INET() and
+ * pj_AF_INET6(). Default is pj_AF_INET().
+ */
+ int af;
+
+ /**
+ * Optional address to bind the socket to. Default is to bind to
+ * PJ_INADDR_ANY and to any available port.
+ */
+ pj_sockaddr bind_addr;
+
+ /**
+ * Optional published address, which is the address to be
+ * advertised as the address of this SIP transport.
+ * By default the bound address will be used as the published address.
+ */
+ pjsip_host_port addr_name;
+
+ /**
+ * Number of simultaneous asynchronous accept() operations to be
+ * supported. It is recommended that the number here corresponds to
+ * the number of processors in the system (or the number of SIP
+ * worker threads).
+ *
+ * Default: 1
+ */
+ unsigned async_cnt;
+
+ /**
+ * QoS traffic type to be set on this transport. When application wants
+ * to apply QoS tagging to the transport, it's preferable to set this
+ * field rather than \a qos_param fields since this is more portable.
+ *
+ * Default is QoS not set.
+ */
+ pj_qos_type qos_type;
+
+ /**
+ * Set the low level QoS parameters to the transport. This is a lower
+ * level operation than setting the \a qos_type field and may not be
+ * supported on all platforms.
+ *
+ * Default is QoS not set.
+ */
+ pj_qos_params qos_params;
+
+} pjsip_tcp_transport_cfg;
+
+
+/**
+ * Initialize pjsip_tcp_transport_cfg structure with default values for
+ * the specifed address family.
+ *
+ * @param cfg The structure to initialize.
+ * @param af Address family to be used.
+ */
+PJ_DECL(void) pjsip_tcp_transport_cfg_default(pjsip_tcp_transport_cfg *cfg,
+ int af);
+
+
+/**
+ * Register support for SIP TCP transport by creating TCP listener on
+ * the specified address and port. This function will create an
+ * instance of SIP TCP transport factory and register it to the
+ * transport manager.
+ *
+ * @param endpt The SIP endpoint.
+ * @param local Optional local address to bind, or specify the
+ * address to bind the server socket to. Both IP
+ * interface address and port fields are optional.
+ * If IP interface address is not specified, socket
+ * will be bound to PJ_INADDR_ANY. If port is not
+ * specified, socket will be bound to any port
+ * selected by the operating system.
+ * @param async_cnt Number of simultaneous asynchronous accept()
+ * operations to be supported. It is recommended that
+ * the number here corresponds to the number of
+ * processors in the system (or the number of SIP
+ * worker threads).
+ * @param p_factory Optional pointer to receive the instance of the
+ * SIP TCP transport factory just created.
+ *
+ * @return PJ_SUCCESS when the transport has been successfully
+ * started and registered to transport manager, or
+ * the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_tcp_transport_start(pjsip_endpoint *endpt,
+ const pj_sockaddr_in *local,
+ unsigned async_cnt,
+ pjsip_tpfactory **p_factory);
+
+
+
+/**
+ * A newer variant of #pjsip_tcp_transport_start(), which allows specifying
+ * the published/public address of the TCP transport.
+ *
+ * @param endpt The SIP endpoint.
+ * @param local Optional local address to bind, or specify the
+ * address to bind the server socket to. Both IP
+ * interface address and port fields are optional.
+ * If IP interface address is not specified, socket
+ * will be bound to PJ_INADDR_ANY. If port is not
+ * specified, socket will be bound to any port
+ * selected by the operating system.
+ * @param a_name Optional published address, which is the address to be
+ * advertised as the address of this SIP transport.
+ * If this argument is NULL, then the bound address
+ * will be used as the published address.
+ * @param async_cnt Number of simultaneous asynchronous accept()
+ * operations to be supported. It is recommended that
+ * the number here corresponds to the number of
+ * processors in the system (or the number of SIP
+ * worker threads).
+ * @param p_factory Optional pointer to receive the instance of the
+ * SIP TCP transport factory just created.
+ *
+ * @return PJ_SUCCESS when the transport has been successfully
+ * started and registered to transport manager, or
+ * the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_tcp_transport_start2(pjsip_endpoint *endpt,
+ const pj_sockaddr_in *local,
+ const pjsip_host_port *a_name,
+ unsigned async_cnt,
+ pjsip_tpfactory **p_factory);
+
+/**
+ * Another variant of #pjsip_tcp_transport_start().
+ *
+ * @param endpt The SIP endpoint.
+ * @param cfg TCP transport settings. Application should initialize
+ * this setting with #pjsip_tcp_transport_cfg_default().
+ * @param p_factory Optional pointer to receive the instance of the
+ * SIP TCP transport factory just created.
+ *
+ * @return PJ_SUCCESS when the transport has been successfully
+ * started and registered to transport manager, or
+ * the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_tcp_transport_start3(
+ pjsip_endpoint *endpt,
+ const pjsip_tcp_transport_cfg *cfg,
+ pjsip_tpfactory **p_factory
+ );
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* PJ_HAS_TCP */
+
+#endif /* __PJSIP_TRANSPORT_TCP_H__ */
diff --git a/pjsip/include/pjsip/sip_transport_tls.h b/pjsip/include/pjsip/sip_transport_tls.h
new file mode 100644
index 0000000..cbc1d75
--- /dev/null
+++ b/pjsip/include/pjsip/sip_transport_tls.h
@@ -0,0 +1,305 @@
+/* $Id: sip_transport_tls.h 3999 2012-03-30 07:10:13Z bennylp $ */
+/*
+ * 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_TRANSPORT_TLS_H__
+#define __PJSIP_TRANSPORT_TLS_H__
+
+/**
+ * @file sip_transport_tls.h
+ * @brief SIP TLS Transport.
+ */
+
+#include <pjsip/sip_transport.h>
+#include <pj/pool.h>
+#include <pj/ssl_sock.h>
+#include <pj/string.h>
+#include <pj/sock_qos.h>
+
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJSIP_TRANSPORT_TLS TLS Transport
+ * @ingroup PJSIP_TRANSPORT
+ * @brief API to create and register TLS transport.
+ * @{
+ * The functions below are used to create TLS transport and register
+ * the transport to the framework.
+ */
+
+/**
+ * The default SSL method to be used by PJSIP.
+ * Default is PJSIP_TLSV1_METHOD
+ */
+#ifndef PJSIP_SSL_DEFAULT_METHOD
+# define PJSIP_SSL_DEFAULT_METHOD PJSIP_TLSV1_METHOD
+#endif
+
+/** SSL protocol method constants. */
+typedef enum pjsip_ssl_method
+{
+ PJSIP_SSL_UNSPECIFIED_METHOD= 0, /**< Default protocol method. */
+ PJSIP_TLSV1_METHOD = 31, /**< Use SSLv1 method. */
+ PJSIP_SSLV2_METHOD = 20, /**< Use SSLv2 method. */
+ PJSIP_SSLV3_METHOD = 30, /**< Use SSLv3 method. */
+ PJSIP_SSLV23_METHOD = 23 /**< Use SSLv23 method. */
+} pjsip_ssl_method;
+
+
+
+
+/**
+ * TLS transport settings.
+ */
+typedef struct pjsip_tls_setting
+{
+ /**
+ * Certificate of Authority (CA) list file.
+ */
+ pj_str_t ca_list_file;
+
+ /**
+ * Public endpoint certificate file, which will be used as client-
+ * side certificate for outgoing TLS connection, and server-side
+ * certificate for incoming TLS connection.
+ */
+ pj_str_t cert_file;
+
+ /**
+ * Optional private key of the endpoint certificate to be used.
+ */
+ pj_str_t privkey_file;
+
+ /**
+ * Password to open private key.
+ */
+ pj_str_t password;
+
+ /**
+ * TLS protocol method from #pjsip_ssl_method, which can be:
+ * - PJSIP_SSL_UNSPECIFIED_METHOD(0): default (which will use
+ * PJSIP_SSL_DEFAULT_METHOD)
+ * - PJSIP_TLSV1_METHOD(1): TLSv1
+ * - PJSIP_SSLV2_METHOD(2): SSLv2
+ * - PJSIP_SSLV3_METHOD(3): SSL3
+ * - PJSIP_SSLV23_METHOD(23): SSL23
+ *
+ * Default is PJSIP_SSL_UNSPECIFIED_METHOD (0), which in turn will
+ * use PJSIP_SSL_DEFAULT_METHOD, which default value is
+ * PJSIP_TLSV1_METHOD.
+ */
+ int method;
+
+ /**
+ * Number of ciphers contained in the specified cipher preference.
+ * If this is set to zero, then default cipher list of the backend
+ * will be used.
+ *
+ * Default: 0 (zero).
+ */
+ unsigned ciphers_num;
+
+ /**
+ * Ciphers and order preference. The #pj_ssl_cipher_get_availables()
+ * can be used to check the available ciphers supported by backend.
+ */
+ pj_ssl_cipher *ciphers;
+
+ /**
+ * Specifies TLS transport behavior on the server TLS certificate
+ * verification result:
+ * - If \a verify_server is disabled (set to PJ_FALSE), TLS transport
+ * will just notify the application via #pjsip_tp_state_callback with
+ * state PJSIP_TP_STATE_CONNECTED regardless TLS verification result.
+ * - If \a verify_server is enabled (set to PJ_TRUE), TLS transport
+ * will be shutdown and application will be notified with state
+ * PJSIP_TP_STATE_DISCONNECTED whenever there is any TLS verification
+ * error, otherwise PJSIP_TP_STATE_CONNECTED will be notified.
+ *
+ * In any cases, application can inspect #pjsip_tls_state_info in the
+ * callback to see the verification detail.
+ *
+ * Default value is PJ_FALSE.
+ */
+ pj_bool_t verify_server;
+
+ /**
+ * Specifies TLS transport behavior on the client TLS certificate
+ * verification result:
+ * - If \a verify_client is disabled (set to PJ_FALSE), TLS transport
+ * will just notify the application via #pjsip_tp_state_callback with
+ * state PJSIP_TP_STATE_CONNECTED regardless TLS verification result.
+ * - If \a verify_client is enabled (set to PJ_TRUE), TLS transport
+ * will be shutdown and application will be notified with state
+ * PJSIP_TP_STATE_DISCONNECTED whenever there is any TLS verification
+ * error, otherwise PJSIP_TP_STATE_CONNECTED will be notified.
+ *
+ * In any cases, application can inspect #pjsip_tls_state_info in the
+ * callback to see the verification detail.
+ *
+ * Default value is PJ_FALSE.
+ */
+ pj_bool_t verify_client;
+
+ /**
+ * When acting as server (incoming TLS connections), reject inocming
+ * connection if client doesn't supply a TLS certificate.
+ *
+ * This setting corresponds to SSL_VERIFY_FAIL_IF_NO_PEER_CERT flag.
+ * Default value is PJ_FALSE.
+ */
+ pj_bool_t require_client_cert;
+
+ /**
+ * TLS negotiation timeout to be applied for both outgoing and
+ * incoming connection. If both sec and msec member is set to zero,
+ * the SSL negotiation doesn't have a timeout.
+ */
+ pj_time_val timeout;
+
+ /**
+ * QoS traffic type to be set on this transport. When application wants
+ * to apply QoS tagging to the transport, it's preferable to set this
+ * field rather than \a qos_param fields since this is more portable.
+ *
+ * Default value is PJ_QOS_TYPE_BEST_EFFORT.
+ */
+ pj_qos_type qos_type;
+
+ /**
+ * Set the low level QoS parameters to the transport. This is a lower
+ * level operation than setting the \a qos_type field and may not be
+ * supported on all platforms.
+ *
+ * By default all settings in this structure are disabled.
+ */
+ pj_qos_params qos_params;
+
+ /**
+ * Specify if the transport should ignore any errors when setting the QoS
+ * traffic type/parameters.
+ *
+ * Default: PJ_TRUE
+ */
+ pj_bool_t qos_ignore_error;
+
+} pjsip_tls_setting;
+
+
+/**
+ * This structure defines TLS transport extended info in <tt>ext_info</tt>
+ * field of #pjsip_transport_state_info for the transport state notification
+ * callback #pjsip_tp_state_callback.
+ */
+typedef struct pjsip_tls_state_info
+{
+ /**
+ * SSL socket info.
+ */
+ pj_ssl_sock_info *ssl_sock_info;
+
+} pjsip_tls_state_info;
+
+
+/**
+ * Initialize TLS setting with default values.
+ *
+ * @param tls_opt The TLS setting to be initialized.
+ */
+PJ_INLINE(void) pjsip_tls_setting_default(pjsip_tls_setting *tls_opt)
+{
+ pj_memset(tls_opt, 0, sizeof(*tls_opt));
+ tls_opt->qos_type = PJ_QOS_TYPE_BEST_EFFORT;
+ tls_opt->qos_ignore_error = PJ_TRUE;
+}
+
+
+/**
+ * Copy TLS setting.
+ *
+ * @param pool The pool to duplicate strings etc.
+ * @param dst Destination structure.
+ * @param src Source structure.
+ */
+PJ_INLINE(void) pjsip_tls_setting_copy(pj_pool_t *pool,
+ pjsip_tls_setting *dst,
+ const pjsip_tls_setting *src)
+{
+ pj_memcpy(dst, src, sizeof(*dst));
+ pj_strdup_with_null(pool, &dst->ca_list_file, &src->ca_list_file);
+ pj_strdup_with_null(pool, &dst->cert_file, &src->cert_file);
+ pj_strdup_with_null(pool, &dst->privkey_file, &src->privkey_file);
+ pj_strdup_with_null(pool, &dst->password, &src->password);
+ if (src->ciphers_num) {
+ unsigned i;
+ dst->ciphers = (pj_ssl_cipher*) pj_pool_calloc(pool, src->ciphers_num,
+ sizeof(pj_ssl_cipher));
+ for (i=0; i<src->ciphers_num; ++i)
+ dst->ciphers[i] = src->ciphers[i];
+ }
+}
+
+
+/**
+ * Register support for SIP TLS transport by creating TLS listener on
+ * the specified address and port. This function will create an
+ * instance of SIP TLS transport factory and register it to the
+ * transport manager.
+ *
+ * @param endpt The SIP endpoint.
+ * @param opt Optional TLS settings.
+ * @param local Optional local address to bind, or specify the
+ * address to bind the server socket to. Both IP
+ * interface address and port fields are optional.
+ * If IP interface address is not specified, socket
+ * will be bound to PJ_INADDR_ANY. If port is not
+ * specified, socket will be bound to any port
+ * selected by the operating system.
+ * @param a_name Optional published address, which is the address to be
+ * advertised as the address of this SIP transport.
+ * If this argument is NULL, then the bound address
+ * will be used as the published address.
+ * @param async_cnt Number of simultaneous asynchronous accept()
+ * operations to be supported. It is recommended that
+ * the number here corresponds to the number of
+ * processors in the system (or the number of SIP
+ * worker threads).
+ * @param p_factory Optional pointer to receive the instance of the
+ * SIP TLS transport factory just created.
+ *
+ * @return PJ_SUCCESS when the transport has been successfully
+ * started and registered to transport manager, or
+ * the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_tls_transport_start(pjsip_endpoint *endpt,
+ const pjsip_tls_setting *opt,
+ const pj_sockaddr_in *local,
+ const pjsip_host_port *a_name,
+ unsigned async_cnt,
+ pjsip_tpfactory **p_factory);
+
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJSIP_TRANSPORT_TLS_H__ */
diff --git a/pjsip/include/pjsip/sip_transport_udp.h b/pjsip/include/pjsip/sip_transport_udp.h
new file mode 100644
index 0000000..f58d1e6
--- /dev/null
+++ b/pjsip/include/pjsip/sip_transport_udp.h
@@ -0,0 +1,235 @@
+/* $Id: sip_transport_udp.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * 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_TRANSPORT_UDP_H__
+#define __PJSIP_TRANSPORT_UDP_H__
+
+/**
+ * @file sip_transport_udp.h
+ * @brief SIP UDP Transport.
+ */
+
+#include <pjsip/sip_transport.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJSIP_TRANSPORT_UDP UDP Transport
+ * @ingroup PJSIP_TRANSPORT
+ * @brief API to create and register UDP transport.
+ * @{
+ * The functions below are used to create UDP transport and register
+ * the transport to the framework.
+ */
+
+/**
+ * Flag that can be specified when calling #pjsip_udp_transport_pause() or
+ * #pjsip_udp_transport_restart().
+ */
+enum
+{
+ /**
+ * This flag tells the transport to keep the existing/internal socket
+ * handle.
+ */
+ PJSIP_UDP_TRANSPORT_KEEP_SOCKET = 1,
+
+ /**
+ * This flag tells the transport to destroy the existing/internal socket
+ * handle. Naturally this flag and PJSIP_UDP_TRANSPORT_KEEP_SOCKET are
+ * mutually exclusive.
+ */
+ PJSIP_UDP_TRANSPORT_DESTROY_SOCKET = 2
+};
+
+
+/**
+ * Start UDP transport.
+ *
+ * @param endpt The SIP endpoint.
+ * @param local Optional local address to bind. If this argument
+ * is NULL, the UDP transport will be bound to arbitrary
+ * UDP port.
+ * @param a_name Published address (only the host and port portion is
+ * used). If this argument is NULL, then the bound address
+ * will be used as the published address.
+ * @param async_cnt Number of simultaneous async operations.
+ * @param p_transport Pointer to receive the transport.
+ *
+ * @return PJ_SUCCESS when the transport has been successfully
+ * started and registered to transport manager, or
+ * the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_udp_transport_start(pjsip_endpoint *endpt,
+ const pj_sockaddr_in *local,
+ const pjsip_host_port *a_name,
+ unsigned async_cnt,
+ pjsip_transport **p_transport);
+
+/**
+ * Start IPv6 UDP transport.
+ */
+PJ_DECL(pj_status_t) pjsip_udp_transport_start6(pjsip_endpoint *endpt,
+ const pj_sockaddr_in6 *local,
+ const pjsip_host_port *a_name,
+ unsigned async_cnt,
+ pjsip_transport **p_transport);
+
+
+/**
+ * Attach IPv4 UDP socket as a new transport and start the transport.
+ *
+ * @param endpt The SIP endpoint.
+ * @param sock UDP socket to use.
+ * @param a_name Published address (only the host and port portion is
+ * used).
+ * @param async_cnt Number of simultaneous async operations.
+ * @param p_transport Pointer to receive the transport.
+ *
+ * @return PJ_SUCCESS when the transport has been successfully
+ * started and registered to transport manager, or
+ * the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_udp_transport_attach(pjsip_endpoint *endpt,
+ pj_sock_t sock,
+ const pjsip_host_port *a_name,
+ unsigned async_cnt,
+ pjsip_transport **p_transport);
+
+
+/**
+ * Attach IPv4 or IPv6 UDP socket as a new transport and start the transport.
+ *
+ * @param endpt The SIP endpoint.
+ * @param type Transport type, which is PJSIP_TRANSPORT_UDP for IPv4
+ * or PJSIP_TRANSPORT_UDP6 for IPv6 socket.
+ * @param sock UDP socket to use.
+ * @param a_name Published address (only the host and port portion is
+ * used).
+ * @param async_cnt Number of simultaneous async operations.
+ * @param p_transport Pointer to receive the transport.
+ *
+ * @return PJ_SUCCESS when the transport has been successfully
+ * started and registered to transport manager, or
+ * the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_udp_transport_attach2(pjsip_endpoint *endpt,
+ pjsip_transport_type_e type,
+ pj_sock_t sock,
+ const pjsip_host_port *a_name,
+ unsigned async_cnt,
+ pjsip_transport **p_transport);
+
+/**
+ * Retrieve the internal socket handle used by the UDP transport. Note
+ * that this socket normally is registered to ioqueue, so if application
+ * wants to make use of this socket, it should temporarily pause the
+ * transport.
+ *
+ * @param transport The UDP transport.
+ *
+ * @return The socket handle, or PJ_INVALID_SOCKET if no socket
+ * is currently being used (for example, when transport
+ * is being paused).
+ */
+PJ_DECL(pj_sock_t) pjsip_udp_transport_get_socket(pjsip_transport *transport);
+
+
+/**
+ * Temporarily pause or shutdown the transport. When transport is being
+ * paused, it cannot be used by the SIP stack to send or receive SIP
+ * messages.
+ *
+ * Two types of operations are supported by this function:
+ * - to temporarily make this transport unavailable for SIP uses, but
+ * otherwise keep the socket handle intact. Application then can
+ * retrieve the socket handle with #pjsip_udp_transport_get_socket()
+ * and use it to send/receive application data (for example, STUN
+ * messages). In this case, application should specify
+ * PJSIP_UDP_TRANSPORT_KEEP_SOCKET when calling this function, and
+ * also to specify this flag when calling #pjsip_udp_transport_restart()
+ * later.
+ * - to temporarily shutdown the transport, including closing down
+ * the internal socket handle. This is useful for example to
+ * temporarily suspend the application for an indefinite period. In
+ * this case, application should specify PJSIP_UDP_TRANSPORT_DESTROY_SOCKET
+ * flag when calling this function, and specify a new socket when
+ * calling #pjsip_udp_transport_restart().
+ *
+ * @param transport The UDP transport.
+ * @param option Pause option.
+ *
+ * @return PJ_SUCCESS if transport is paused successfully,
+ * or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_udp_transport_pause(pjsip_transport *transport,
+ unsigned option);
+
+/**
+ * Restart the transport. Several operations are supported by this function:
+ * - if transport was made temporarily unavailable to SIP stack with
+ * pjsip_udp_transport_pause() and PJSIP_UDP_TRANSPORT_KEEP_SOCKET,
+ * application can make the transport available to the SIP stack
+ * again, by specifying PJSIP_UDP_TRANSPORT_KEEP_SOCKET flag here.
+ * - if application wants to replace the internal socket with a new
+ * socket, it must specify PJSIP_UDP_TRANSPORT_DESTROY_SOCKET when
+ * calling this function, so that the internal socket will be destroyed
+ * if it hasn't been closed. In this case, application has two choices
+ * on how to create the new socket: 1) to let the transport create
+ * the new socket, in this case the \a sock option should be set
+ * to \a PJ_INVALID_SOCKET and optionally the \a local parameter can be
+ * filled with the desired address and port where the new socket
+ * should be bound to, or 2) to specify its own socket to be used
+ * by this transport, by specifying a valid socket in \a sock argument
+ * and set the \a local argument to NULL. In both cases, application
+ * may specify the published address of the socket in \a a_name
+ * argument.
+ *
+ * @param transport The UDP transport.
+ * @param option Restart option.
+ * @param sock Optional socket to be used by the transport.
+ * @param local The address where the socket should be bound to.
+ * If this argument is NULL, socket will be bound
+ * to any available port.
+ * @param a_name Optionally specify the published address for
+ * this transport. If the socket is not replaced
+ * (PJSIP_UDP_TRANSPORT_KEEP_SOCKET flag is
+ * specified), then if this argument is NULL, the
+ * previous value will be used. If the socket is
+ * replaced and this argument is NULL, the bound
+ * address will be used as the published address
+ * of the transport.
+ *
+ * @return PJ_SUCCESS if transport can be restarted, or
+ * the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_udp_transport_restart(pjsip_transport *transport,
+ unsigned option,
+ pj_sock_t sock,
+ const pj_sockaddr_in *local,
+ const pjsip_host_port *a_name);
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJSIP_TRANSPORT_UDP_H__ */
diff --git a/pjsip/include/pjsip/sip_types.h b/pjsip/include/pjsip/sip_types.h
new file mode 100644
index 0000000..8cd98ae
--- /dev/null
+++ b/pjsip/include/pjsip/sip_types.h
@@ -0,0 +1,257 @@
+/* $Id: sip_types.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * 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_TYPES_H__
+#define __PJSIP_SIP_TYPES_H__
+
+
+/*
+ * My note: Doxygen PJSIP and PJSIP_CORE group is declared in
+ * sip_config.h
+ */
+
+/**
+ * @file sip_types.h
+ * @brief Basic PJSIP types.
+ */
+
+#include <pjsip/sip_config.h>
+#include <pj/types.h>
+
+/**
+ * @addtogroup PJSIP_BASE
+ */
+
+/* @defgroup PJSIP_TYPES Basic Data Types
+ * @ingroup PJSIP_BASE
+ * @brief Basic data types.
+ * @{
+ */
+
+
+
+/**
+ * Forward declaration for SIP transport.
+ */
+typedef struct pjsip_transport pjsip_transport;
+
+/**
+ * Forward declaration for transport manager.
+ */
+typedef struct pjsip_tpmgr pjsip_tpmgr;
+
+/**
+ * Transport types.
+ */
+typedef enum pjsip_transport_type_e
+{
+ /** Unspecified. */
+ PJSIP_TRANSPORT_UNSPECIFIED,
+
+ /** UDP. */
+ PJSIP_TRANSPORT_UDP,
+
+ /** TCP. */
+ PJSIP_TRANSPORT_TCP,
+
+ /** TLS. */
+ PJSIP_TRANSPORT_TLS,
+
+ /** SCTP. */
+ PJSIP_TRANSPORT_SCTP,
+
+ /** Loopback (stream, reliable) */
+ PJSIP_TRANSPORT_LOOP,
+
+ /** Loopback (datagram, unreliable) */
+ PJSIP_TRANSPORT_LOOP_DGRAM,
+
+ /** Start of user defined transport */
+ PJSIP_TRANSPORT_START_OTHER,
+
+ /** Start of IPv6 transports */
+ PJSIP_TRANSPORT_IPV6 = 128,
+
+ /** UDP over IPv6 */
+ PJSIP_TRANSPORT_UDP6 = PJSIP_TRANSPORT_UDP + PJSIP_TRANSPORT_IPV6,
+
+ /** TCP over IPv6 */
+ PJSIP_TRANSPORT_TCP6 = PJSIP_TRANSPORT_TCP + PJSIP_TRANSPORT_IPV6
+
+} pjsip_transport_type_e;
+
+
+/**
+ * Forward declaration for endpoint (sip_endpoint.h).
+ */
+typedef struct pjsip_endpoint pjsip_endpoint;
+
+/**
+ * Forward declaration for transactions (sip_transaction.h).
+ */
+typedef struct pjsip_transaction pjsip_transaction;
+
+/**
+ * Forward declaration for events (sip_event.h).
+ */
+typedef struct pjsip_event pjsip_event;
+
+/**
+ * Forward declaration for transmit data/buffer (sip_transport.h).
+ */
+typedef struct pjsip_tx_data pjsip_tx_data;
+
+/**
+ * Forward declaration for receive data/buffer (sip_transport.h).
+ */
+typedef struct pjsip_rx_data pjsip_rx_data;
+
+/**
+ * Forward declaration for message (sip_msg.h).
+ */
+typedef struct pjsip_msg pjsip_msg;
+
+/**
+ * Forward declaration for message body (sip_msg.h).
+ */
+typedef struct pjsip_msg_body pjsip_msg_body;
+
+/**
+ * Forward declaration for header field (sip_msg.h).
+ */
+typedef struct pjsip_hdr pjsip_hdr;
+
+/**
+ * Forward declaration for URI (sip_uri.h).
+ */
+typedef struct pjsip_uri pjsip_uri;
+
+/**
+ * Forward declaration for SIP method (sip_msg.h)
+ */
+typedef struct pjsip_method pjsip_method;
+
+/**
+ * Opaque data type for the resolver engine (sip_resolve.h).
+ */
+typedef struct pjsip_resolver_t pjsip_resolver_t;
+
+/**
+ * Forward declaration for credential.
+ */
+typedef struct pjsip_cred_info pjsip_cred_info;
+
+
+/**
+ * Forward declaration for module (sip_module.h).
+ */
+typedef struct pjsip_module pjsip_module;
+
+
+/**
+ * Forward declaration for user agent type (sip_ua_layer.h).
+ */
+typedef pjsip_module pjsip_user_agent;
+
+/**
+ * Forward declaration for dialog (sip_dialog.h).
+ */
+typedef struct pjsip_dialog pjsip_dialog;
+
+/**
+ * Transaction role.
+ */
+typedef enum pjsip_role_e
+{
+ PJSIP_ROLE_UAC, /**< Role is UAC. */
+ PJSIP_ROLE_UAS, /**< Role is UAS. */
+
+ /* Alias: */
+
+ PJSIP_UAC_ROLE = PJSIP_ROLE_UAC, /**< Role is UAC. */
+ PJSIP_UAS_ROLE = PJSIP_ROLE_UAS /**< Role is UAS. */
+
+} pjsip_role_e;
+
+
+/**
+ * General purpose buffer.
+ */
+typedef struct pjsip_buffer
+{
+ /** The start of the buffer. */
+ char *start;
+
+ /** Pointer to current end of the buffer, which also indicates the position
+ of subsequent buffer write.
+ */
+ char *cur;
+
+ /** The absolute end of the buffer. */
+ char *end;
+
+} pjsip_buffer;
+
+
+/**
+ * General host:port pair, used for example as Via sent-by.
+ */
+typedef struct pjsip_host_port
+{
+ pj_str_t host; /**< Host part or IP address. */
+ int port; /**< Port number. */
+} pjsip_host_port;
+
+/**
+ * Host information.
+ */
+typedef struct pjsip_host_info
+{
+ unsigned flag; /**< Flags of pjsip_transport_flags_e. */
+ pjsip_transport_type_e type; /**< Transport type. */
+ pjsip_host_port addr; /**< Address information. */
+} pjsip_host_info;
+
+
+/**
+ * Convert exception ID into pj_status_t status.
+ *
+ * @param exception_id Exception Id.
+ *
+ * @return Error code for the specified exception Id.
+ */
+PJ_DECL(pj_status_t) pjsip_exception_to_status(int exception_id);
+
+/**
+ * Return standard pj_status_t status from current exception.
+ */
+#define PJSIP_RETURN_EXCEPTION() pjsip_exception_to_status(PJ_GET_EXCEPTION())
+
+/**
+ * Attributes to inform that the function may throw exceptions.
+ */
+#define PJSIP_THROW_SPEC(list)
+
+
+/**
+ * @}
+ */
+
+#endif /* __PJSIP_SIP_TYPES_H__ */
+
diff --git a/pjsip/include/pjsip/sip_ua_layer.h b/pjsip/include/pjsip/sip_ua_layer.h
new file mode 100644
index 0000000..4c69e45
--- /dev/null
+++ b/pjsip/include/pjsip/sip_ua_layer.h
@@ -0,0 +1,162 @@
+/* $Id: sip_ua_layer.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * 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_UA_LAYER_H__
+#define __PJSIP_SIP_UA_LAYER_H__
+
+/**
+ * @file sip_ua_layer.h
+ * @brief SIP User Agent Layer Module
+ */
+#include <pjsip/sip_types.h>
+
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJSIP_UA Base User Agent Layer/Common Dialog Layer
+ * @brief Dialog management.
+ *
+ * This module provides basic dialog management, which is used by higher
+ * layer dialog usages such as INVITE sessions and SIP Event Subscription
+ * framework (RFC 3265). Application should link with <b>pjsip-core</b>
+ * library to use this base UA layer. The base UA layer module is initialized
+ * with #pjsip_ua_init_module().
+ */
+
+/**
+ * @defgroup PJSUA_UA SIP User Agent Module
+ * @ingroup PJSIP_UA
+ * @brief Provides dialog management.
+ * @{
+ *
+ * Application MUST initialize the user agent layer module by calling
+ * #pjsip_ua_init_module() before using any of the dialog API, and link
+ * the application with with <b>pjsip-core</b> library.
+ */
+
+/** User agent initialization parameter. */
+typedef struct pjsip_ua_init_param
+{
+ /** Callback to be called when the UA layer detects that outgoing
+ * dialog has forked.
+ */
+ pjsip_dialog* (*on_dlg_forked)(pjsip_dialog *first_set, pjsip_rx_data *res);
+} pjsip_ua_init_param;
+
+/**
+ * Initialize user agent layer and register it to the specified endpoint.
+ *
+ * @param endpt The endpoint where the user agent will be
+ * registered.
+ * @param prm UA initialization parameter.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_ua_init_module(pjsip_endpoint *endpt,
+ const pjsip_ua_init_param *prm);
+
+/**
+ * Get the instance of the user agent.
+ *
+ * @return The user agent module instance.
+ */
+PJ_DECL(pjsip_user_agent*) pjsip_ua_instance(void);
+
+
+/**
+ * Retrieve the current number of dialog-set currently registered
+ * in the hash table. Note that dialog-set is different than dialog
+ * when the request forks. In this case, all dialogs created from
+ * the original request will belong to the same dialog set. When
+ * no forking occurs, the number of dialog sets will be equal to
+ * the number of dialogs.
+ *
+ * @return Number of dialog sets.
+ */
+PJ_DECL(pj_uint32_t) pjsip_ua_get_dlg_set_count(void);
+
+
+/**
+ * Find a dialog with the specified Call-ID and tags properties. This
+ * function may optionally lock the matching dialog instance before
+ * returning it back to the caller.
+ *
+ * @param call_id The call ID to be matched.
+ * @param local_tag The local tag to be matched.
+ * @param remote_tag The remote tag to be matched.
+ * @param lock_dialog If non-zero, instruct the function to lock the
+ * matching dialog with #pjsip_dlg_inc_lock().
+ * Application is responsible to release the dialog's
+ * lock after it has finished manipulating the dialog,
+ * by calling #pjsip_dlg_dec_lock().
+ *
+ * @return The matching dialog instance, or NULL if no matching
+ * dialog is found.
+ */
+PJ_DECL(pjsip_dialog*) pjsip_ua_find_dialog(const pj_str_t *call_id,
+ const pj_str_t *local_tag,
+ const pj_str_t *remote_tag,
+ pj_bool_t lock_dialog);
+
+/**
+ * Destroy the user agent layer.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_ua_destroy(void);
+
+/**
+ * Dump user agent contents (e.g. all dialogs).
+ *
+ * @param detail If non-zero, list of dialogs will be printed.
+ */
+PJ_DECL(void) pjsip_ua_dump(pj_bool_t detail);
+
+/**
+ * Get the endpoint instance of a user agent module.
+ *
+ * @param ua The user agent instance.
+ *
+ * @return The endpoint instance where the user agent is
+ * registered.
+ */
+PJ_DECL(pjsip_endpoint*) pjsip_ua_get_endpt(pjsip_user_agent *ua);
+
+
+/**
+ * @}
+ */
+
+
+/*
+ * Internal (called by sip_dialog.c).
+ */
+
+PJ_DECL(pj_status_t) pjsip_ua_register_dlg( pjsip_user_agent *ua,
+ pjsip_dialog *dlg );
+PJ_DECL(pj_status_t) pjsip_ua_unregister_dlg(pjsip_user_agent *ua,
+ pjsip_dialog *dlg );
+
+
+PJ_END_DECL
+
+
+#endif /* __PJSIP_SIP_UA_LAYER_H__ */
+
diff --git a/pjsip/include/pjsip/sip_uri.h b/pjsip/include/pjsip/sip_uri.h
new file mode 100644
index 0000000..849392f
--- /dev/null
+++ b/pjsip/include/pjsip/sip_uri.h
@@ -0,0 +1,468 @@
+/* $Id: sip_uri.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * 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_URI_H__
+#define __PJSIP_SIP_URI_H__
+
+/**
+ * @file sip_uri.h
+ * @brief SIP URL Structures and Manipulations
+ */
+
+#include <pjsip/sip_types.h>
+#include <pjsip/sip_config.h>
+#include <pj/list.h>
+#include <pjlib-util/scanner.h>
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup PJSIP_URI URI
+ * @brief URI types and manipulations.
+ * @ingroup PJSIP_MSG
+ */
+
+/**
+ * @addtogroup PJSIP_URI_PARAM URI Parameter Container
+ * @ingroup PJSIP_URI
+ * @brief Generic parameter elements container.
+ * @{
+ */
+
+/**
+ * Generic parameter, normally used in other_param or header_param.
+ */
+typedef struct pjsip_param
+{
+ PJ_DECL_LIST_MEMBER(struct pjsip_param); /**< Generic list member. */
+ pj_str_t name; /**< Param/header name. */
+ pj_str_t value; /**< Param/header value. */
+} pjsip_param;
+
+
+/**
+ * Find the specified parameter name in the list. The name will be compared
+ * in case-insensitive comparison.
+ *
+ * @param param_list List of parameters to find.
+ * @param name Parameter/header name to find.
+ *
+ * @return The parameter if found, or NULL.
+ */
+PJ_DECL(pjsip_param*) pjsip_param_find( const pjsip_param *param_list,
+ const pj_str_t *name );
+
+
+/**
+ * Alias for pjsip_param_find()
+ */
+PJ_INLINE(pjsip_param*) pjsip_param_cfind(const pjsip_param *param_list,
+ const pj_str_t *name)
+{
+ return pjsip_param_find(param_list, name);
+}
+
+/**
+ * Compare two parameter lists.
+ *
+ * @param param_list1 First parameter list.
+ * @param param_list2 Second parameter list.
+ * @param ig_nf If set to 1, do not compare parameters that only
+ * appear in one of the list.
+ *
+ * @return Zero if the parameter list are equal, non-zero
+ * otherwise.
+ */
+PJ_DECL(int) pjsip_param_cmp(const pjsip_param *param_list1,
+ const pjsip_param *param_list2,
+ pj_bool_t ig_nf);
+
+/**
+ * Duplicate the parameters.
+ *
+ * @param pool Pool to allocate memory from.
+ * @param dst_list Destination list.
+ * @param src_list Source list.
+ */
+PJ_DECL(void) pjsip_param_clone(pj_pool_t *pool, pjsip_param *dst_list,
+ const pjsip_param *src_list);
+
+/**
+ * Duplicate the parameters.
+ *
+ * @param pool Pool to allocate memory from.
+ * @param dst_list Destination list.
+ * @param src_list Source list.
+ */
+PJ_DECL(void) pjsip_param_shallow_clone(pj_pool_t *pool,
+ pjsip_param *dst_list,
+ const pjsip_param *src_list);
+
+/**
+ * Print parameters.
+ *
+ * @param param_list The parameter list.
+ * @param buf Buffer.
+ * @param size Size of buffer.
+ * @param pname_unres Specification of allowed characters in pname.
+ * @param pvalue_unres Specification of allowed characters in pvalue.
+ * @param sep Separator character (either ';', ',', or '?').
+ * When separator is set to '?', this function will
+ * automatically adjust the separator character to
+ * '&' after the first parameter is printed.
+ *
+ * @return The number of bytes printed, or -1 on errr.
+ */
+PJ_DECL(pj_ssize_t) pjsip_param_print_on(const pjsip_param *param_list,
+ char *buf, pj_size_t size,
+ const pj_cis_t *pname_unres,
+ const pj_cis_t *pvalue_unres,
+ int sep);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup PJSIP_URI_GENERIC Generic URI
+ * @ingroup PJSIP_URI
+ * @brief Generic representation for all types of URI.
+ * @{
+ */
+
+/**
+ * URI context.
+ */
+typedef enum pjsip_uri_context_e
+{
+ PJSIP_URI_IN_REQ_URI, /**< The URI is in Request URI. */
+ PJSIP_URI_IN_FROMTO_HDR, /**< The URI is in From/To header. */
+ PJSIP_URI_IN_CONTACT_HDR, /**< The URI is in Contact header. */
+ PJSIP_URI_IN_ROUTING_HDR, /**< The URI is in Route/Record-Route header. */
+ PJSIP_URI_IN_OTHER /**< Other context (web page, business card, etc.) */
+} pjsip_uri_context_e;
+
+/**
+ * URI 'virtual' function table.
+ * All types of URI in this library (such as sip:, sips:, tel:, and name-addr)
+ * will have pointer to this table as their first struct member. This table
+ * provides polimorphic behaviour to the URI.
+ */
+typedef struct pjsip_uri_vptr
+{
+ /**
+ * Get URI scheme.
+ * @param uri the URI (self).
+ * @return the URI scheme.
+ */
+ const pj_str_t* (*p_get_scheme)(const void *uri);
+
+ /**
+ * Get the URI object contained by this URI, or the URI itself if
+ * it doesn't contain another URI.
+ * @param uri the URI (self).
+ */
+ void* (*p_get_uri)(void *uri);
+
+ /**
+ * Print URI components to the buffer, following the rule of which
+ * components are allowed for the context.
+ * @param context the context where the URI will be placed.
+ * @param uri the URI (self).
+ * @param buf the buffer.
+ * @param size the size of the buffer.
+ * @return the length printed.
+ */
+ pj_ssize_t (*p_print)(pjsip_uri_context_e context,
+ const void *uri,
+ char *buf, pj_size_t size);
+
+ /**
+ * Compare two URIs according to the context.
+ * @param context the context.
+ * @param uri1 the first URI (self).
+ * @param uri2 the second URI.
+ * @return PJ_SUCCESS if equal, or otherwise the error status which
+ * should point to the mismatch part.
+ */
+ pj_status_t (*p_compare)(pjsip_uri_context_e context,
+ const void *uri1, const void *uri2);
+
+ /**
+ * Clone URI.
+ * @param pool the pool.
+ * @param the URI to clone (self).
+ * @return new URI.
+ */
+ void *(*p_clone)(pj_pool_t *pool, const void *uri);
+
+} pjsip_uri_vptr;
+
+
+/**
+ * The declaration of 'base class' for all URI scheme.
+ */
+struct pjsip_uri
+{
+ /** All URIs must have URI virtual function table as their first member. */
+ pjsip_uri_vptr *vptr;
+};
+
+/**
+ * This macro checks that the URL is a "sip:" or "sips:" URL.
+ * @param url The URL (pointer to)
+ * @return non-zero if TRUE.
+ */
+#define PJSIP_URI_SCHEME_IS_SIP(url) \
+ (pj_strnicmp2(pjsip_uri_get_scheme(url), "sip", 3)==0)
+
+/**
+ * This macro checks that the URL is a "sips:" URL (not SIP).
+ * @param url The URL (pointer to)
+ * @return non-zero if TRUE.
+ */
+#define PJSIP_URI_SCHEME_IS_SIPS(url) \
+ (pj_strnicmp2(pjsip_uri_get_scheme(url), "sips", 4)==0)
+
+/**
+ * This macro checks that the URL is a "tel:" URL.
+ * @param url The URL (pointer to)
+ * @return non-zero if TRUE.
+ */
+#define PJSIP_URI_SCHEME_IS_TEL(url) \
+ (pj_strnicmp2(pjsip_uri_get_scheme(url), "tel", 3)==0)
+
+
+/**
+ * Generic function to get the URI scheme.
+ * @param uri the URI object.
+ * @return the URI scheme.
+ */
+PJ_INLINE(const pj_str_t*) pjsip_uri_get_scheme(const void *uri)
+{
+ return (*((pjsip_uri*)uri)->vptr->p_get_scheme)(uri);
+}
+
+/**
+ * Generic function to get the URI object contained by this URI, or the URI
+ * itself if it doesn't contain another URI.
+ *
+ * @param uri the URI.
+ * @return the URI.
+ */
+PJ_INLINE(void*) pjsip_uri_get_uri(const void *uri)
+{
+ return (*((pjsip_uri*)uri)->vptr->p_get_uri)((void*)uri);
+}
+
+/**
+ * Generic function to compare two URIs.
+ *
+ * @param context Comparison context.
+ * @param uri1 The first URI.
+ * @param uri2 The second URI.
+ * @return PJ_SUCCESS if equal, or otherwise the error status which
+ * should point to the mismatch part.
+ */
+PJ_INLINE(pj_status_t) pjsip_uri_cmp(pjsip_uri_context_e context,
+ const void *uri1, const void *uri2)
+{
+ return (*((const pjsip_uri*)uri1)->vptr->p_compare)(context, uri1, uri2);
+}
+
+/**
+ * Generic function to print an URI object.
+ *
+ * @param context Print context.
+ * @param uri The URI to print.
+ * @param buf The buffer.
+ * @param size Size of the buffer.
+ * @return Length printed.
+ */
+PJ_INLINE(int) pjsip_uri_print(pjsip_uri_context_e context,
+ const void *uri,
+ char *buf, pj_size_t size)
+{
+ return (*((const pjsip_uri*)uri)->vptr->p_print)(context, uri, buf, size);
+}
+
+/**
+ * Generic function to clone an URI object.
+ *
+ * @param pool Pool.
+ * @param uri URI to clone.
+ * @return New URI.
+ */
+PJ_INLINE(void*) pjsip_uri_clone( pj_pool_t *pool, const void *uri )
+{
+ return (*((const pjsip_uri*)uri)->vptr->p_clone)(pool, uri);
+}
+
+
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup PJSIP_SIP_URI SIP URI Scheme and Name address
+ * @ingroup PJSIP_URI
+ * @brief SIP URL structure ("sip:" and "sips:")
+ * @{
+ */
+
+
+/**
+ * SIP and SIPS URL scheme.
+ */
+typedef struct pjsip_sip_uri
+{
+ pjsip_uri_vptr *vptr; /**< Pointer to virtual function table.*/
+ pj_str_t user; /**< Optional user part. */
+ pj_str_t passwd; /**< Optional password part. */
+ pj_str_t host; /**< Host part, always exists. */
+ int port; /**< Optional port number, or zero. */
+ pj_str_t user_param; /**< Optional user parameter */
+ pj_str_t method_param; /**< Optional method parameter. */
+ pj_str_t transport_param; /**< Optional transport parameter. */
+ int ttl_param; /**< Optional TTL param, or -1. */
+ int lr_param; /**< Optional loose routing param, or zero */
+ pj_str_t maddr_param; /**< Optional maddr param */
+ pjsip_param other_param; /**< Other parameters grouped together. */
+ pjsip_param header_param; /**< Optional header parameter. */
+} pjsip_sip_uri;
+
+
+/**
+ * SIP name-addr, which typically appear in From, To, and Contact header.
+ * The SIP name-addr contains a generic URI and a display name.
+ */
+typedef struct pjsip_name_addr
+{
+ /** Pointer to virtual function table. */
+ pjsip_uri_vptr *vptr;
+
+ /** Optional display name. */
+ pj_str_t display;
+
+ /** URI part. */
+ pjsip_uri *uri;
+
+} pjsip_name_addr;
+
+
+/**
+ * Create new SIP URL and initialize all fields with zero or NULL.
+ * @param pool The pool.
+ * @param secure Flag to indicate whether secure transport should be used.
+ * @return SIP URL.
+ */
+PJ_DECL(pjsip_sip_uri*) pjsip_sip_uri_create( pj_pool_t *pool,
+ pj_bool_t secure );
+
+/**
+ * Change the SIP URI scheme to sip or sips based on the secure flag.
+ * This would not change anything except the scheme.
+ * @param uri The URI
+ * @param secure Non-zero if sips is wanted.
+ */
+PJ_DECL(void) pjsip_sip_uri_set_secure( pjsip_sip_uri *uri,
+ pj_bool_t secure );
+
+/**
+ * Initialize SIP URL (all fields are set to NULL or zero).
+ * @param url The URL.
+ * @param secure Create sips URI?
+ */
+PJ_DECL(void) pjsip_sip_uri_init(pjsip_sip_uri *url, pj_bool_t secure);
+
+/**
+ * Perform full assignment to the SIP URL.
+ * @param pool The pool.
+ * @param url Destination URL.
+ * @param rhs The source URL.
+ */
+PJ_DECL(void) pjsip_sip_uri_assign(pj_pool_t *pool, pjsip_sip_uri *url,
+ const pjsip_sip_uri *rhs);
+
+/**
+ * Create new instance of name address and initialize all fields with zero or
+ * NULL.
+ * @param pool The pool.
+ * @return New SIP name address.
+ */
+PJ_DECL(pjsip_name_addr*) pjsip_name_addr_create(pj_pool_t *pool);
+
+/**
+ * Initialize with default value.
+ * @param name_addr The name address.
+ */
+PJ_DECL(void) pjsip_name_addr_init(pjsip_name_addr *name_addr);
+
+/**
+ * Perform full assignment to the name address.
+ * @param pool The pool.
+ * @param addr The destination name address.
+ * @param rhs The source name address.
+ */
+PJ_DECL(void) pjsip_name_addr_assign(pj_pool_t *pool,
+ pjsip_name_addr *addr,
+ const pjsip_name_addr *rhs);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup PJSIP_OTHER_URI Other URI schemes
+ * @ingroup PJSIP_URI
+ * @brief Container for non SIP/tel URI scheme (e.g. "http:", "mailto:")
+ * @{
+ */
+
+/**
+ * Generic URI container for non SIP/tel URI scheme.
+ */
+typedef struct pjsip_other_uri
+{
+ pjsip_uri_vptr *vptr; /**< Pointer to virtual function table. */
+ pj_str_t scheme; /**< The URI scheme (e.g. "mailto") */
+ pj_str_t content; /**< The whole URI content */
+} pjsip_other_uri;
+
+
+/**
+ * Create a generic URI object.
+ *
+ * @param pool The pool to allocate memory from.
+ *
+ * @return The URI instance.
+ */
+PJ_DECL(pjsip_other_uri*) pjsip_other_uri_create(pj_pool_t *pool);
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+#endif /* __PJSIP_URL_H__ */
+
diff --git a/pjsip/include/pjsip/sip_util.h b/pjsip/include/pjsip/sip_util.h
new file mode 100644
index 0000000..6efa45f
--- /dev/null
+++ b/pjsip/include/pjsip/sip_util.h
@@ -0,0 +1,861 @@
+/* $Id: sip_util.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * 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_MISC_H__
+#define __PJSIP_SIP_MISC_H__
+
+#include <pjsip/sip_msg.h>
+#include <pjsip/sip_transport.h>
+#include <pjsip/sip_resolve.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJSIP_ENDPT_TARGET_URI Target URI Management
+ * @ingroup PJSIP_CORE_CORE
+ * @brief Management of target URI's in case of redirection
+ * @{
+ * This module provides utility functions to manage target set for UAC.
+ * The target set is provided as pjsip_target_set structure. Initially,
+ * the target set for UAC contains only one target, that is the target of
+ * the initial request. When 3xx/redirection class response is received,
+ * the UAC can use the functionality of this module to add the URI's listed
+ * in the Contact header(s) in the response to the target set, and retry
+ * sending the request to the next destination/target. The UAC may retry
+ * this sequentially until one of the target answers with succesful/2xx
+ * response, or one target returns global error/6xx response, or all targets
+ * are exhausted.
+ *
+ * This module is currently used by the \ref PJSIP_INV.
+ */
+
+/**
+ * This structure describes a target, which can be chained together to form
+ * a target set. Each target contains an URI, priority (as q-value), and
+ * the last status code and reason phrase received from the target, if the
+ * target has been contacted. If the target has not been contacted, the
+ * status code field will be zero.
+ */
+typedef struct pjsip_target
+{
+ PJ_DECL_LIST_MEMBER(struct pjsip_target);/**< Standard list element */
+ pjsip_uri *uri; /**< The target URI */
+ int q1000; /**< q-value multiplied by 1000 */
+ pjsip_status_code code; /**< Last status code received */
+ pj_str_t reason; /**< Last reason phrase received */
+} pjsip_target;
+
+
+/**
+ * This describes a target set. A target set contains a linked-list of
+ * pjsip_target.
+ */
+typedef struct pjsip_target_set
+{
+ pjsip_target head; /**< Target linked-list head */
+ pjsip_target *current; /**< Current target. */
+} pjsip_target_set;
+
+
+/**
+ * These enumerations specify the action to be performed to a redirect
+ * response.
+ */
+typedef enum pjsip_redirect_op
+{
+ /**
+ * Reject the redirection to the current target. The UAC will
+ * select the next target from the target set if exists.
+ */
+ PJSIP_REDIRECT_REJECT,
+
+ /**
+ * Accept the redirection to the current target. The INVITE request
+ * will be resent to the current target.
+ */
+ PJSIP_REDIRECT_ACCEPT,
+
+ /**
+ * Defer the redirection decision, for example to request permission
+ * from the end user.
+ */
+ PJSIP_REDIRECT_PENDING,
+
+ /**
+ * Stop the whole redirection process altogether. This will cause
+ * the invite session to be disconnected.
+ */
+ PJSIP_REDIRECT_STOP
+
+} pjsip_redirect_op;
+
+
+/**
+ * Initialize target set. This will empty the list of targets in the
+ * target set.
+ *
+ * @param tset The target set.
+ */
+PJ_INLINE(void) pjsip_target_set_init(pjsip_target_set *tset)
+{
+ pj_list_init(&tset->head);
+ tset->current = NULL;
+}
+
+
+/**
+ * Add an URI to the target set, if the URI is not already in the target set.
+ * The URI comparison rule of pjsip_uri_cmp() will be used to determine the
+ * equality of this URI compared to existing URI's in the target set. The
+ * URI will be cloned using the specified memory pool before it is added to
+ * the list.
+ *
+ * The first URI added to the target set will also be made current target
+ * by this function.
+ *
+ * @param tset The target set.
+ * @param pool The memory pool to be used to duplicate the URI.
+ * @param uri The URI to be checked and added.
+ * @param q1000 The q-value multiplied by 1000.
+ *
+ * @return PJ_SUCCESS if the URI was added to the target set,
+ * or PJ_EEXISTS if the URI already exists in the target
+ * set, or other error codes.
+ */
+PJ_DECL(pj_status_t) pjsip_target_set_add_uri(pjsip_target_set *tset,
+ pj_pool_t *pool,
+ const pjsip_uri *uri,
+ int q1000);
+
+/**
+ * Extract URI's in the Contact headers of the specified (response) message
+ * and add them to the target set. This function will also check if the
+ * URI's already exist in the target set before adding them to the list.
+ *
+ * @param tset The target set.
+ * @param pool The memory pool to be used to duplicate the URI's.
+ * @param msg SIP message from which the Contact headers will be
+ * scanned and the URI's to be extracted, checked, and
+ * added to the target set.
+ *
+ * @return PJ_SUCCESS if at least one URI was added to the
+ * target set, or PJ_EEXISTS if all URI's in the message
+ * already exists in the target set or if the message
+ * doesn't contain usable Contact headers, or other error
+ * codes.
+ */
+PJ_DECL(pj_status_t) pjsip_target_set_add_from_msg(pjsip_target_set *tset,
+ pj_pool_t *pool,
+ const pjsip_msg *msg);
+
+/**
+ * Get the next target to be retried. This function will scan the target set
+ * for target which hasn't been tried, and return one target with the
+ * highest q-value, if such target exists. This function will return NULL
+ * if there is one target with 2xx or 6xx code or if all targets have been
+ * tried.
+ *
+ * @param tset The target set.
+ *
+ * @return The next target to be tried, or NULL if all targets have
+ * been tried or at least one target returns 2xx or 6xx
+ * response.
+ */
+PJ_DECL(pjsip_target*)
+pjsip_target_set_get_next(const pjsip_target_set *tset);
+
+
+/**
+ * Set the specified target as the current target in the target set. The
+ * current target may be used by application to keep track on which target
+ * is currently being operated on.
+ *
+ * @param tset The target set.
+ * @param target The target to be set as current target.
+ *
+ * @return PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_target_set_set_current(pjsip_target_set *tset,
+ pjsip_target *target);
+
+
+/**
+ * Set the status code and reason phrase of the specified target.
+ *
+ * @param target The target.
+ * @param pool The memory pool to be used to duplicate the reason phrase.
+ * @param code The SIP status code to be set to the target.
+ * @param reason The reason phrase to be set to the target.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjsip_target_assign_status(pjsip_target *target,
+ pj_pool_t *pool,
+ int status_code,
+ const pj_str_t *reason);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup PJSIP_ENDPT_STATELESS Message Creation and Stateless Operations
+ * @ingroup PJSIP_CORE_CORE
+ * @brief Utilities to create various messages and base function to send messages.
+ * @{
+ */
+
+/**
+ * Create an independent request message. This can be used to build any
+ * 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.
+ * @param method SIP Method.
+ * @param target Target URI.
+ * @param from URL to put in From header.
+ * @param to URL to put in To header.
+ * @param contact Contact to be put as Contact header value, hence
+ * the format must follow RFC 3261 Section 20.10:
+ * When the header field value contains a display
+ * name, the URI including all URI parameters is
+ * enclosed in "<" and ">". If no "<" and ">" are
+ * present, all parameters after the URI are header
+ * parameters, not URI parameters. The display name
+ * can be tokens, or a quoted string, if a larger
+ * character set is desired.
+ * @param call_id Optional Call-ID (put NULL to generate unique Call-ID).
+ * @param cseq Optional CSeq (put -1 to generate random CSeq).
+ * @param text Optional text body (put NULL to omit body).
+ * @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_request( pjsip_endpoint *endpt,
+ const pjsip_method *method,
+ const pj_str_t *target,
+ const pj_str_t *from,
+ const pj_str_t *to,
+ const pj_str_t *contact,
+ const pj_str_t *call_id,
+ int cseq,
+ const pj_str_t *text,
+ pjsip_tx_data **p_tdata);
+
+/**
+ * Create an independent request message from the specified headers. This
+ * 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.
+ *
+ * @param endpt Endpoint instance.
+ * @param method SIP Method.
+ * @param target Target URI.
+ * @param from From header.
+ * @param to To header.
+ * @param contact Contact header.
+ * @param call_id Optional Call-ID (put NULL to generate unique Call-ID).
+ * @param cseq Optional CSeq (put -1 to generate random CSeq).
+ * @param text Optional text body (put NULL to omit body).
+ * @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_request_from_hdr( pjsip_endpoint *endpt,
+ const pjsip_method *method,
+ const pjsip_uri *target,
+ const pjsip_from_hdr *from,
+ const pjsip_to_hdr *to,
+ const pjsip_contact_hdr *contact,
+ const pjsip_cid_hdr *call_id,
+ int cseq,
+ const pj_str_t *text,
+ pjsip_tx_data **p_tdata);
+
+/**
+ * Construct a minimal response message for the received request. This function
+ * will construct all the Via, Record-Route, Call-ID, From, To, CSeq, and
+ * Call-ID headers from the request.
+ *
+ * Note: the txdata reference counter is set to ZERO!.
+ *
+ * @param endpt The endpoint.
+ * @param rdata The request receive data.
+ * @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 st_code,
+ const pj_str_t *st_text,
+ pjsip_tx_data **p_tdata);
+
+/**
+ * Construct a full ACK request for the received non-2xx final response.
+ * This utility function is normally called by the transaction to construct
+ * an ACK request to 3xx-6xx final response.
+ * The generation of ACK message for 2xx final response is different than
+ * this one.
+ *
+ * @param endpt The endpoint.
+ * @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(pj_status_t) pjsip_endpt_create_ack( pjsip_endpoint *endpt,
+ const pjsip_tx_data *tdata,
+ const pjsip_rx_data *rdata,
+ pjsip_tx_data **ack);
+
+
+/**
+ * Construct CANCEL request for the previously sent request.
+ *
+ * @param endpt The endpoint.
+ * @param tdata The transmit buffer for the request being cancelled.
+ * @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_cancel( pjsip_endpoint *endpt,
+ const pjsip_tx_data *tdata,
+ pjsip_tx_data **p_tdata);
+
+
+/**
+ * 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.
+ *
+ * Note there was a change in the behavior of this function since version
+ * 0.5.10.2. Previously this function may modify the request when strict
+ * route is present (to update request URI and route-set). This is no
+ * longer the case now, and this process is done in separate function
+ * (see #pjsip_process_route_set()).
+ *
+ * @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.
+ *
+ * @see pjsip_process_route_set
+ */
+PJ_DECL(pj_status_t) pjsip_get_request_dest(const pjsip_tx_data *tdata,
+ pjsip_host_info *dest_info );
+
+
+/**
+ * Process route-set found in the request and calculate 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.
+ *
+ * @see pjsip_get_request_addr
+ */
+PJ_DECL(pj_status_t) pjsip_process_route_set(pjsip_tx_data *tdata,
+ pjsip_host_info *dest_info );
+
+
+/**
+ * Swap the request URI and strict route back to the original position
+ * before #pjsip_process_route_set() function is called. If no strict
+ * route URI was found by #pjsip_process_route_set(), this function will
+ * do nothing.
+ *
+ * This function should only used internally by PJSIP client authentication
+ * module.
+ *
+ * @param tdata Transmit data containing request message.
+ */
+PJ_DECL(void) pjsip_restore_strict_route_set(pjsip_tx_data *tdata);
+
+
+/**
+ * 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;
+
+ /** 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;
+
+
+/**
+ * Declaration for callback function to be specified in
+ * #pjsip_endpt_send_request_stateless(), #pjsip_endpt_send_response(), or
+ * #pjsip_endpt_send_response2().
+ *
+ * @param st Structure to keep transmission state.
+ * @param sent Number of bytes sent.
+ * @param cont When current transmission fails, specify whether
+ * the function should fallback to next destination.
+ */
+typedef void (*pjsip_send_callback)(pjsip_send_state *st, pj_ssize_t sent,
+ pj_bool_t *cont);
+
+/**
+ * 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.
+ * @param token Arbitrary token to be given back on the callback.
+ * @param cb Optional callback to notify transmission status (also
+ * gives chance for application to discontinue retrying
+ * sending to alternate address).
+ *
+ * @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,
+ pjsip_send_callback cb);
+
+/**
+ * This is a low-level function to send raw data to a destination.
+ *
+ * See also #pjsip_endpt_send_raw_to_uri().
+ *
+ * @param endpt The SIP endpoint instance.
+ * @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 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_endpt_send_raw(pjsip_endpoint *endpt,
+ pjsip_transport_type_e tp_type,
+ const pjsip_tpselector *sel,
+ const void *raw_data,
+ pj_size_t data_len,
+ const pj_sockaddr_t *addr,
+ int addr_len,
+ void *token,
+ pjsip_tp_send_callback cb);
+
+/**
+ * Send raw data to the specified destination URI. The actual destination
+ * address will be calculated from the URI, using normal SIP URI to host
+ * resolution.
+ *
+ * See also #pjsip_endpt_send_raw().
+ *
+ * @param endpt The SIP endpoint instance.
+ * @param dst_uri Destination address URI.
+ * @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 raw_data The data to be sent.
+ * @param data_len The length of the data.
+ * @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_endpt_send_raw_to_uri(pjsip_endpoint *endpt,
+ const pj_str_t *dst_uri,
+ const pjsip_tpselector *sel,
+ const void *raw_data,
+ pj_size_t data_len,
+ void *token,
+ pjsip_tp_send_callback cb);
+
+/**
+ * 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 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,
+ 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,
+ pjsip_send_callback cb);
+
+/**
+ * This is a convenient function which wraps #pjsip_get_response_addr() and
+ * #pjsip_endpt_send_response() in a single function.
+ *
+ * @param endpt The endpoint instance.
+ * @param rdata The original request to be responded.
+ * @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_response2(pjsip_endpoint *endpt,
+ pjsip_rx_data *rdata,
+ pjsip_tx_data *tdata,
+ void *token,
+ pjsip_send_callback cb);
+
+/**
+ * This composite function sends response message statelessly to an incoming
+ * request message. Internally it calls #pjsip_endpt_create_response() and
+ * #pjsip_endpt_send_response().
+ *
+ * @param endpt The endpoint instance.
+ * @param rdata The incoming request message.
+ * @param st_code Status code of the response.
+ * @param st_text Optional status text of the response.
+ * @param hdr_list Optional header list to be added to the response.
+ * @param body Optional message body to be added to the response.
+ *
+ * @return PJ_SUCCESS if response message has successfully been
+ * sent.
+ */
+PJ_DECL(pj_status_t) pjsip_endpt_respond_stateless(pjsip_endpoint *endpt,
+ pjsip_rx_data *rdata,
+ int st_code,
+ const pj_str_t *st_text,
+ const pjsip_hdr *hdr_list,
+ const pjsip_msg_body *body);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup PJSIP_TRANSACT_UTIL Stateful Operations
+ * @ingroup PJSIP_TRANSACT
+ * @brief Utility function to send requests/responses statefully.
+ * @{
+ */
+
+/**
+ * This composite function creates and sends response statefully for the
+ * incoming request.
+ *
+ * @param endpt The endpoint instance.
+ * @param tsx_user The module to be registered as transaction user.
+ * @param rdata The incoming request message.
+ * @param st_code Status code of the response.
+ * @param st_text Optional status text of the response.
+ * @param hdr_list Optional header list to be added to the response.
+ * @param body Optional message body to be added to the response.
+ * @param p_tsx Optional pointer to receive the transaction which was
+ * created to send the response.
+ *
+ * @return PJ_SUCCESS if response message has successfully been
+ * created.
+ */
+PJ_DECL(pj_status_t) pjsip_endpt_respond( pjsip_endpoint *endpt,
+ pjsip_module *tsx_user,
+ pjsip_rx_data *rdata,
+ int st_code,
+ const pj_str_t *st_text,
+ const pjsip_hdr *hdr_list,
+ const pjsip_msg_body *body,
+ pjsip_transaction **p_tsx );
+
+/**
+ * Type of callback to be specified in #pjsip_endpt_send_request().
+ *
+ * @param token The token that was given in #pjsip_endpt_send_request()
+ * @param e Completion event.
+ */
+typedef void (*pjsip_endpt_send_callback)(void *token, pjsip_event *e);
+
+/**
+ * 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_request 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.
+ * The value is in miliseconds.
+ * @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,
+ pj_int32_t timeout,
+ void *token,
+ pjsip_endpt_send_callback cb);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup PJSIP_PROXY_CORE Core Proxy Layer
+ * @brief Core proxy operations
+ * @{
+ */
+
+/**
+ * Create new request message to be forwarded upstream to new destination URI
+ * in uri. The new request is a full/deep clone of the request received in
+ * rdata, unless if other copy mechanism is specified in the options.
+ * The branch parameter, if not NULL, will be used as the branch-param in
+ * the Via header. If it is NULL, then a unique branch parameter will be used.
+ *
+ * Note: this function DOES NOT perform Route information preprocessing as
+ * described in RFC 3261 Section 16.4. Application must take care of
+ * removing/updating the Route headers according of the rules as
+ * described in that section.
+ *
+ * @param endpt The endpoint instance.
+ * @param rdata The incoming request message.
+ * @param uri The URI where the request will be forwarded to.
+ * @param branch Optional branch parameter. Application may specify its
+ * own branch, for example if it wishes to perform loop
+ * detection. If the branch parameter is not specified,
+ * this function will generate its own by calling
+ * #pjsip_calculate_branch_id() function.
+ * @param options Optional option flags when duplicating the message.
+ * @param tdata The result.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_endpt_create_request_fwd(pjsip_endpoint *endpt,
+ pjsip_rx_data *rdata,
+ const pjsip_uri *uri,
+ const pj_str_t *branch,
+ unsigned options,
+ pjsip_tx_data **tdata);
+
+
+
+/**
+ * Create new response message to be forwarded downstream by the proxy from
+ * the response message found in rdata. Note that this function practically
+ * will clone the response as is, i.e. without checking the validity of the
+ * response or removing top most Via header. This function will perform
+ * full/deep clone of the response, unless other copy mechanism is used in
+ * the options.
+ *
+ * @param endpt The endpoint instance.
+ * @param rdata The incoming response message.
+ * @param options Optional option flags when duplicate the message.
+ * @param tdata The result
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_endpt_create_response_fwd( pjsip_endpoint *endpt,
+ pjsip_rx_data *rdata,
+ unsigned options,
+ pjsip_tx_data **tdata);
+
+
+
+/**
+ * Create a globally unique branch parameter based on the information in
+ * the incoming request message, for the purpose of creating a new request
+ * for forwarding. This is the default implementation used by
+ * #pjsip_endpt_create_request_fwd() function if the branch parameter is
+ * not specified.
+ *
+ * The default implementation here will just create an MD5 hash of the
+ * top-most Via.
+ *
+ * Note that the returned string was allocated from rdata's pool.
+ *
+ * @param rdata The incoming request message.
+ *
+ * @return Unique branch-ID string.
+ */
+PJ_DECL(pj_str_t) pjsip_calculate_branch_id( pjsip_rx_data *rdata );
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+#endif /* __PJSIP_SIP_MISC_H__ */
+