* #36737: switch back to svn repo, remove assert in sip_transaction.c
diff --git a/jni/pjproject-android/.svn/pristine/85/8590672aaecfe4e2f70afc416fa2f8ce527aa91b.svn-base b/jni/pjproject-android/.svn/pristine/85/8590672aaecfe4e2f70afc416fa2f8ce527aa91b.svn-base
new file mode 100644
index 0000000..a17c74c
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/85/8590672aaecfe4e2f70afc416fa2f8ce527aa91b.svn-base
@@ -0,0 +1,822 @@
+/* $Id$ */
+/* 
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#ifndef __PJMEDIA_SDP_NEG_H__
+#define __PJMEDIA_SDP_NEG_H__
+
+
+/**
+ * @file sdp_neg.h
+ * @brief SDP negotiator header file.
+ */
+/**
+ * @defgroup PJMEDIA_SDP_NEG SDP Negotiation State Machine (Offer/Answer Model, RFC 3264)
+ * @ingroup PJMEDIA_SESSION
+ * @brief SDP Negotiation State Machine (Offer/Answer Model, RFC 3264)
+ * @{
+ *
+ * The header file <b><pjmedia/sdp_neg.h></b> contains the declaration
+ * of SDP offer and answer negotiator. SDP offer and answer model is described
+ * in RFC 3264 <b>"An Offer/Answer Model with Session Description Protocol 
+ * (SDP)"</b>.
+ *
+ * The SDP negotiator is represented with opaque type \a pjmedia_sdp_neg.
+ * This structure contains negotiation state and several SDP session 
+ * descriptors currently being used in the negotiation.
+ *
+ *
+ * \section sdpneg_state_dia SDP Negotiator State Diagram
+ *
+ * The following diagram describes the state transition diagram of the
+ * SDP negotiator.
+ * 
+ * <pre>
+ *                                              
+ *                                              modify_local_offer()
+ *     create_w_local_offer()  +-------------+  send_local_offer()
+ *     ----------------------->| LOCAL_OFFER |<-----------------------
+ *    |                        +-------------+______                  |
+ *    |                               |             \_____________    |
+ *    |           set_remote_answer() |           cancel_offer()  \   |
+ *    |                               V                            v  |
+ * +--+---+                     +-----------+     negotiate()     +-~----+
+ * | NULL |                     | WAIT_NEGO |-------------------->| DONE |
+ * +------+                     +-----------+                     +------+
+ *    |                               A      ______________________^  |
+ *    |            set_local_answer() |     /     cancel_offer()      |
+ *    |                               |    /                          |
+ *    |                        +--------------+   set_remote_offer()  |
+ *     ----------------------->| REMOTE_OFFER |<----------------------
+ *     create_w_remote_offer() +--------------+
+ *
+ * </pre>
+ *
+ *
+ *
+ * \section sdpneg_offer_answer SDP Offer/Answer Model with Negotiator
+ *
+ * \subsection sdpneg_create_offer Creating Initial Offer
+ *
+ * Application creates an offer by manualy building the SDP session descriptor
+ * (pjmedia_sdp_session), or request PJMEDIA endpoint (pjmedia_endpt) to 
+ * create SDP session descriptor based on capabilities that present in the
+ * endpoint by calling #pjmedia_endpt_create_sdp().
+ *
+ * Application then creates SDP negotiator instance by calling
+ * #pjmedia_sdp_neg_create_w_local_offer(), passing the SDP offer in the
+ * function arguments. The SDP negotiator keeps a copy of current local offer,
+ * and update its state to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER.
+ *
+ * Application can then send the initial SDP offer that it creates to
+ * remote peer using signaling protocol such as SIP.
+ *
+ *
+ * \subsection sdpneg_subseq_offer Generating Subsequent Offer
+ *
+ * The negotiator can only create subsequent offer after it has finished
+ * the negotiation process of previous offer/answer session (i.e. the
+ * negotiator state is PJMEDIA_SDP_NEG_STATE_DONE).
+ *
+ * If any previous negotiation process was successfull (i.e. the return 
+ * value of #pjmedia_sdp_neg_negotiate() was PJ_SUCCESS), the negotiator
+ * keeps both active local and active remote SDP.
+ *
+ * If application does not want send modified offer, it can just send
+ * the active local SDP as the offer. In this case, application calls
+ * #pjmedia_sdp_neg_send_local_offer() to get the active local SDP.
+ * 
+ * If application wants to modify it's local offer, it MUST inform 
+ * the negotiator about the modified SDP by calling 
+ * #pjmedia_sdp_neg_modify_local_offer().
+ *
+ * In both cases, the negotiator will internally create a copy of the offer,
+ * and move it's state to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER, where it
+ * waits until application passes the remote answer.
+ *
+ *
+ * \subsection sdpneg_receive_offer Receiving Initial Offer
+ *
+ * Application receives an offer in the incoming request from remote to
+ * establish multimedia session, such as incoming INVITE message with SDP
+ * body. 
+ *
+ * Initially, when the initial offer is received, application creates the 
+ * SDP negotiator by calling #pjmedia_sdp_neg_create_w_remote_offer(),
+ * specifying the remote SDP offer in one of the argument. 
+ *
+ * At this stage, application may or may not ready to create an answer.
+ * For example, a SIP B2BUA needs to make outgoing call and receive SDP
+ * from the outgoing call leg in order to create a SDP answer to the
+ * incoming call leg.
+ *
+ * If application is not ready to create an answer, it passes NULL as
+ * the local SDP when it calls #pjmedia_sdp_neg_create_w_remote_offer().
+ *
+ * The section @ref sdpneg_create_answer describes the case when 
+ * application is ready to create a SDP answer.
+ *
+ *
+ * \subsection sdpneg_subseq_offer Receiving Subsequent Offer
+ *
+ * Application passes subsequent SDP offer received from remote by
+ * calling #pjmedia_sdp_neg_set_remote_offer().
+ *
+ * The negotiator can only receive subsequent offer after it has finished
+ * the negotiation process of previous offer/answer session (i.e. the
+ * negotiator state is PJMEDIA_SDP_NEG_STATE_DONE).
+ *
+ *
+ * \subsection sdpneg_recv_answer Receiving SDP Answer
+ *
+ * When application receives SDP answer from remote, it informs the
+ * negotiator by calling #pjmedia_sdp_neg_set_remote_answer(). The
+ * negotiator validates the answer (#pjmedia_sdp_validate()), and if
+ * succeeds, it moves it's state to PJMEDIA_SDP_NEG_STATE_WAIT_NEGO.
+ *
+ * Application then instruct the negotiator to negotiate the remote
+ * answer by calling #pjmedia_sdp_neg_negotiate(). The purpose of
+ * this negotiation is to verify remote answer, and update the initial
+ * offer according to the answer. For example, the initial offer may
+ * specify that a stream is \a sendrecv, while the answer specifies
+ * that remote stream is \a inactive. In this case, the negotiator
+ * will update the stream in the local active media as \a inactive
+ * too.
+ *
+ * If #pjmedia_sdp_neg_negotiate() returns PJ_SUCCESS, the negotiator will
+ * keep the updated local answer and remote answer internally. These two 
+ * SDPs are called active local SDP and active remote SDP, as it describes 
+ * currently active session.
+ *
+ * Application can retrieve the active local SDP by calling
+ * #pjmedia_sdp_neg_get_active_local(), and active remote SDP by calling
+ * #pjmedia_sdp_neg_get_active_remote().
+ *
+ * If #pjmedia_sdp_neg_negotiate() returns failure (i.e. not PJ_SUCCESS),
+ * it WILL NOT update its active local and active remote SDP.
+ *
+ * Regardless of the return status of the #pjmedia_sdp_neg_negotiate(), 
+ * the negotiator state will move to PJMEDIA_SDP_NEG_STATE_DONE.
+ * 
+ *
+ * \subsection sdpneg_cancel_offer Cancelling an Offer
+ *
+ * In other case, after an offer is generated (negotiator state is in
+ * PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER), the answer may not be received, and
+ * application wants the negotiator to reset itself to its previous state.
+ * Consider this example:
+ *
+ *  - media has been established, and negotiator state is
+ *    PJMEDIA_SDP_NEG_STATE_DONE.
+ *  - application generates a new offer for re-INVITE, so in this case
+ *    it would either call #pjmedia_sdp_neg_send_local_offer() or
+ *    #pjmedia_sdp_neg_modify_local_offer()
+ *  - the negotiator state moves to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER
+ *  - the re-INVITE was rejected with an error
+ *
+ * Since an answer is not received, it is necessary to reset the negotiator
+ * state back to PJMEDIA_SDP_NEG_STATE_DONE so that the negotiator can
+ * create or receive new offer.
+ *
+ * This can be accomplished by calling #pjmedia_sdp_neg_cancel_offer(),
+ * to reset the negotiator state back to PJMEDIA_SDP_NEG_STATE_DONE. In
+ * this case, both active local and active remote will not be modified.
+ *
+ * \subsection sdpneg_create_answer Generating SDP Answer
+ *
+ * After remote offer has been set in the negotiator, application can 
+ * request the SDP negotiator to generate appropriate answer based on local 
+ * capability.
+ *
+ * To do this, first the application MUST have an SDP describing its local
+ * capabilities. This SDP can be built manually, or application can generate
+ * SDP to describe local media endpoint capability by calling 
+ * #pjmedia_endpt_create_sdp(). When the application is a SIP B2BUA, 
+ * application can treat the SDP received from the outgoing call leg as if
+ * it was it's local capability.
+ * 
+ * The local SDP session descriptor DOES NOT have to match the SDP offer.
+ * For example, it can have more or less media lines than the offer, or
+ * their order may be different than the offer. The negotiator is capable
+ * to match and reorder local SDP according to remote offer, and create
+ * an answer that is suitable for the offer.
+ *
+ * After local SDP capability has been acquired, application can create
+ * a SDP answer.
+ *
+ * If application does not already have the negotiator instance, it creates
+ * one by calling #pjmedia_sdp_neg_create_w_remote_offer(), specifying 
+ * both remote SDP offer and local SDP as the arguments. The SDP negotiator
+ * validates both remote and local SDP by calling #pjmedia_sdp_validate(),
+ * and if both SDPs are valid, the negotiator state will move to
+ * PJMEDIA_SDP_NEG_STATE_WAIT_NEGO where it is ready to negotiate the
+ * offer and answer.
+ *
+ * If application already has the negotiator instance, it sets the local
+ * SDP in the negotiator by calling #pjmedia_sdp_neg_set_local_answer().
+ * The SDP negotiator then validates local SDP (#pjmedia_sdp_validate() ),
+ * and if it is  valid, the negotiator state will move to
+ * PJMEDIA_SDP_NEG_STATE_WAIT_NEGO where it is ready to negotiate the
+ * offer and answer.
+ *
+ * After the SDP negotiator state has moved to PJMEDIA_SDP_NEG_STATE_WAIT_NEGO,
+ * application calls #pjmedia_sdp_neg_negotiate() to instruct the SDP
+ * negotiator to negotiate both offer and answer. This function returns
+ * PJ_SUCCESS if an answer can be generated AND at least one media stream
+ * is active in the session.
+ *
+ * If #pjmedia_sdp_neg_negotiate() returns PJ_SUCCESS, the negotiator will
+ * keep the remote offer and local answer internally. These two SDPs are
+ * called active local SDP and active remote SDP, as it describes currently
+ * active session.
+ *
+ * Application can retrieve the active local SDP by calling
+ * #pjmedia_sdp_neg_get_active_local(), and send this SDP to remote as the
+ * SDP answer.
+ *
+ * If #pjmedia_sdp_neg_negotiate() returns failure (i.e. not PJ_SUCCESS),
+ * it WILL NOT update its active local and active remote SDP.
+ *
+ * Regardless of the return status of the #pjmedia_sdp_neg_negotiate(), 
+ * the negotiator state will move to PJMEDIA_SDP_NEG_STATE_DONE.
+ *
+ *
+ */
+
+#include <pjmedia/sdp.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * This enumeration describes SDP negotiation state. 
+ */
+enum pjmedia_sdp_neg_state
+{
+    /** 
+     * This is the state of SDP negoator before it is initialized. 
+     */
+    PJMEDIA_SDP_NEG_STATE_NULL,
+
+    /** 
+     * This state occurs when SDP negotiator has sent our offer to remote and
+     * it is waiting for answer. 
+     */
+    PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER,
+
+    /** 
+     * This state occurs when SDP negotiator has received offer from remote
+     * and currently waiting for local answer.
+     */
+    PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER,
+
+    /**
+     * This state occurs when an offer (either local or remote) has been 
+     * provided with answer. The SDP negotiator is ready to negotiate both
+     * session descriptors. Application can call #pjmedia_sdp_neg_negotiate()
+     * immediately to begin negotiation process.
+     */
+    PJMEDIA_SDP_NEG_STATE_WAIT_NEGO,
+
+    /**
+     * This state occurs when SDP negotiation has completed, either 
+     * successfully or not.
+     */
+    PJMEDIA_SDP_NEG_STATE_DONE
+};
+
+
+/**
+ * @see pjmedia_sdp_neg_state
+ */
+typedef enum pjmedia_sdp_neg_state pjmedia_sdp_neg_state;
+
+
+/**
+ * Opaque declaration of SDP negotiator.
+ */
+typedef struct pjmedia_sdp_neg pjmedia_sdp_neg;
+
+
+/**
+ * Flags to be given to pjmedia_sdp_neg_modify_local_offer2().
+ */
+typedef enum pjmedia_mod_offer_flag
+{
+   /**
+    * Allow media type in the SDP to be changed.
+    * When generating a new offer, in the case that a media line doesn't match
+    * the active SDP, the new media line will be considered to replace the
+    * existing media at the same position.
+    */
+   PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE = 1
+
+} pjmedia_mod_offer_flag;
+
+
+/**
+ * Get the state string description of the specified state.
+ *
+ * @param state		Negotiator state.
+ *
+ * @return		String description of the state.
+ */
+PJ_DECL(const char*) pjmedia_sdp_neg_state_str(pjmedia_sdp_neg_state state);
+
+
+/**
+ * Create the SDP negotiator with local offer. The SDP negotiator then
+ * will move to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER state, where it waits
+ * until it receives answer from remote. When SDP answer from remote is
+ * received, application must call #pjmedia_sdp_neg_set_remote_answer().
+ *
+ * After calling this function, application should send the local SDP offer
+ * to remote party using signaling protocol such as SIP and wait for SDP 
+ * answer.
+ *
+ * @param pool		Pool to allocate memory. The pool's lifetime needs
+ *			to be valid for the duration of the negotiator.
+ * @param local		The initial local capability.
+ * @param p_neg		Pointer to receive the negotiator instance.
+ *
+ * @return		PJ_SUCCESS on success, or the appropriate error
+ *			code.
+ */
+PJ_DECL(pj_status_t) 
+pjmedia_sdp_neg_create_w_local_offer( pj_pool_t *pool,
+				      const pjmedia_sdp_session *local,
+				      pjmedia_sdp_neg **p_neg);
+
+/**
+ * Initialize the SDP negotiator with remote offer, and optionally
+ * specify the initial local capability, if known. Application normally 
+ * calls this function when it receives initial offer from remote. 
+ *
+ * If local media capability is specified, this capability will be set as
+ * initial local capability of the negotiator, and after this function is
+ * called, the SDP negotiator state will move to state
+ * PJMEDIA_SDP_NEG_STATE_WAIT_NEGO, and the negotiation function can be 
+ * called. 
+ *
+ * If local SDP is not specified, the negotiator will not have initial local
+ * capability, and after this function is called the negotiator state will 
+ * move to PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER state. Application MUST supply
+ * local answer later with #pjmedia_sdp_neg_set_local_answer(), before
+ * calling the negotiation function.
+ *
+ * @param pool		Pool to allocate memory. The pool's lifetime needs
+ *			to be valid for the duration of the negotiator.
+ * @param initial	Optional initial local capability.
+ * @param remote	The remote offer.
+ * @param p_neg		Pointer to receive the negotiator instance.
+ *
+ * @return		PJ_SUCCESS on success, or the appropriate error
+ *			code.
+ */
+PJ_DECL(pj_status_t) 
+pjmedia_sdp_neg_create_w_remote_offer(pj_pool_t *pool,
+				      const pjmedia_sdp_session *initial,
+				      const pjmedia_sdp_session *remote,
+				      pjmedia_sdp_neg **p_neg);
+
+/**
+ * This specifies the behavior of the SDP negotiator when responding to an
+ * offer, whether it should rather use the codec preference as set by
+ * remote, or should it rather use the codec preference as specified by
+ * local endpoint.
+ *
+ * For example, suppose incoming call has codec order "8 0 3", while 
+ * local codec order is "3 0 8". If remote codec order is preferable,
+ * the selected codec will be 8, while if local codec order is preferable,
+ * the selected codec will be 3.
+ *
+ * By default, the value in PJMEDIA_SDP_NEG_PREFER_REMOTE_CODEC_ORDER will
+ * be used.
+ *
+ * @param neg		The SDP negotiator instance.
+ * @param prefer_remote	If non-zero, the negotiator will use the codec
+ *			order as specified in remote offer. If zero, it
+ *			will prefer to use the local codec order.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_set_prefer_remote_codec_order(pjmedia_sdp_neg *neg,
+					      pj_bool_t prefer_remote);
+
+/**
+ * This specifies the behavior of the SDP negotiator when responding to an
+ * offer, whether it should answer with multiple formats or not.
+ *
+ * By default, the value in PJMEDIA_SDP_NEG_ANSWER_MULTIPLE_CODECS will
+ * be used.
+ *
+ * @param neg           The SDP negotiator instance.
+ * @param answer_multiple
+ *                      If non-zero, the negotiator will respond with
+ *                      multiple formats. If zero only a single format
+ *                      will be returned.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_set_answer_multiple_codecs(pjmedia_sdp_neg *neg,
+                                           pj_bool_t answer_multiple);
+
+
+/**
+ * Get SDP negotiator state.
+ *
+ * @param neg		The SDP negotiator instance.
+ *
+ * @return		The negotiator state.
+ */
+PJ_DECL(pjmedia_sdp_neg_state)
+pjmedia_sdp_neg_get_state( pjmedia_sdp_neg *neg );
+
+/**
+ * Get the currently active local SDP. Application can only call this
+ * function after negotiation has been done, or otherwise there won't be
+ * active SDPs. Calling this function will not change the state of the 
+ * negotiator.
+ *
+ * @param neg		The SDP negotiator instance.
+ * @param local		Pointer to receive the local active SDP.
+ *
+ * @return		PJ_SUCCESS if local active SDP is present.
+ */
+PJ_DECL(pj_status_t) 
+pjmedia_sdp_neg_get_active_local( pjmedia_sdp_neg *neg,
+				  const pjmedia_sdp_session **local);
+
+/**
+ * Get the currently active remote SDP. Application can only call this
+ * function after negotiation has been done, or otherwise there won't be
+ * active SDPs. Calling this function will not change the state of the 
+ * negotiator.
+ *
+ * @param neg		The SDP negotiator instance.
+ * @param remote	Pointer to receive the remote active SDP.
+ *
+ * @return		PJ_SUCCESS if remote active SDP is present.
+ */
+PJ_DECL(pj_status_t) 
+pjmedia_sdp_neg_get_active_remote( pjmedia_sdp_neg *neg,
+				   const pjmedia_sdp_session **remote);
+
+
+/**
+ * Determine whether remote sent answer (as opposed to offer) on the
+ * last negotiation. This function can only be called in state
+ * PJMEDIA_SDP_NEG_STATE_DONE.
+ *
+ * @param neg		The SDP negotiator instance.
+ *
+ * @return		Non-zero if it was remote who sent answer,
+ *			otherwise zero if it was local who supplied
+ *			answer.
+ */
+PJ_DECL(pj_bool_t)
+pjmedia_sdp_neg_was_answer_remote(pjmedia_sdp_neg *neg);
+
+
+/**
+ * Get the current remote SDP offer or answer. Application can only 
+ * call this function in state PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER or
+ * PJMEDIA_SDP_NEG_STATE_WAIT_NEGO, or otherwise there won't be remote 
+ * SDP offer/answer. Calling this  function will not change the state 
+ * of the negotiator.
+ *
+ * @param neg		The SDP negotiator instance.
+ * @param remote	Pointer to receive the current remote offer or
+ *			answer.
+ *
+ * @return		PJ_SUCCESS if the negotiator currently has
+ *			remote offer or answer.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_get_neg_remote( pjmedia_sdp_neg *neg,
+				const pjmedia_sdp_session **remote);
+
+
+/**
+ * Get the current local SDP offer or answer. Application can only 
+ * call this function in state PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER or
+ * PJMEDIA_SDP_NEG_STATE_WAIT_NEGO, or otherwise there won't be local 
+ * SDP offer/answer. Calling this function will not change the state 
+ * of the negotiator.
+ *
+ * @param neg		The SDP negotiator instance.
+ * @param local		Pointer to receive the current local offer or
+ *			answer.
+ *
+ * @return		PJ_SUCCESS if the negotiator currently has
+ *			local offer or answer.
+ */
+PJ_DECL(pj_status_t) 
+pjmedia_sdp_neg_get_neg_local( pjmedia_sdp_neg *neg,
+			       const pjmedia_sdp_session **local);
+
+/**
+ * Modify local session with a new SDP and treat this as a new offer. 
+ * This function can only be called in state PJMEDIA_SDP_NEG_STATE_DONE.
+ * After calling this function, application can send the SDP as offer 
+ * to remote party, using signaling protocol such as SIP.
+ * The negotiator state will move to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER,
+ * where it waits for SDP answer from remote. See also
+ * #pjmedia_sdp_neg_modify_local_offer2()
+ *
+ * @param pool		Pool to allocate memory. The pool's lifetime needs
+ *			to be valid for the duration of the negotiator.
+ * @param neg		The SDP negotiator instance.
+ * @param local		The new local SDP.
+ *
+ * @return		PJ_SUCCESS on success, or the appropriate
+ *			error code.
+ */
+PJ_DECL(pj_status_t) 
+pjmedia_sdp_neg_modify_local_offer( pj_pool_t *pool,
+				    pjmedia_sdp_neg *neg,
+				    const pjmedia_sdp_session *local);
+
+/**
+ * Modify local session with a new SDP and treat this as a new offer. 
+ * This function can only be called in state PJMEDIA_SDP_NEG_STATE_DONE.
+ * After calling this function, application can send the SDP as offer 
+ * to remote party, using signaling protocol such as SIP.
+ * The negotiator state will move to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER,
+ * where it waits for SDP answer from remote.
+ *
+ * @param pool		Pool to allocate memory. The pool's lifetime needs
+ *			to be valid for the duration of the negotiator.
+ * @param neg		The SDP negotiator instance.
+ * @param flags         Bitmask from pjmedia_mod_offer_flag.
+ * @param local		The new local SDP.
+ *
+ * @return		PJ_SUCCESS on success, or the appropriate
+ *			error code.
+ */
+PJ_DECL(pj_status_t) 
+pjmedia_sdp_neg_modify_local_offer2( pj_pool_t *pool,
+				     pjmedia_sdp_neg *neg,
+                                     unsigned flags,
+				     const pjmedia_sdp_session *local);
+
+/**
+ * This function can only be called in PJMEDIA_SDP_NEG_STATE_DONE state.
+ * Application calls this function to retrieve currently active
+ * local SDP, and then send the SDP to remote as an offer. The negotiator
+ * state will then move to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER, where it waits
+ * for SDP answer from remote. 
+ *
+ * When SDP answer has been received from remote, application must call 
+ * #pjmedia_sdp_neg_set_remote_answer().
+ *
+ * @param pool		Pool to allocate memory. The pool's lifetime needs
+ *			to be valid for the duration of the negotiator.
+ * @param neg		The SDP negotiator instance.
+ * @param offer		Pointer to receive active local SDP to be
+ *			offered to remote.
+ *
+ * @return		PJ_SUCCESS if local offer can be created.
+ */
+PJ_DECL(pj_status_t) 
+pjmedia_sdp_neg_send_local_offer( pj_pool_t *pool,
+			          pjmedia_sdp_neg *neg,
+				  const pjmedia_sdp_session **offer);
+
+/**
+ * This function can only be called in PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER
+ * state, i.e. after application calls #pjmedia_sdp_neg_send_local_offer()
+ * function. Application calls this function when it receives SDP answer
+ * from remote. After this function is called, the negotiator state will
+ * move to PJMEDIA_SDP_NEG_STATE_WAIT_NEGO, and application can call the
+ * negotiation function #pjmedia_sdp_neg_negotiate().
+ *
+ * @param pool		Pool to allocate memory. The pool's lifetime needs
+ *			to be valid for the duration of the negotiator.
+ * @param neg		The SDP negotiator instance.
+ * @param remote	The remote answer.
+ *
+ * @return		PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) 
+pjmedia_sdp_neg_set_remote_answer( pj_pool_t *pool,
+				   pjmedia_sdp_neg *neg,
+				   const pjmedia_sdp_session *remote);
+
+
+
+/**
+ * This function can only be called in PJMEDIA_SDP_NEG_STATE_DONE state. 
+ * Application calls this function when it receives SDP offer from remote.
+ * After this function is called, the negotiator state will move to 
+ * PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER, and application MUST call the
+ * #pjmedia_sdp_neg_set_local_answer() to set local answer before it can
+ * call the negotiation function.
+ *
+ * @param pool		Pool to allocate memory. The pool's lifetime needs
+ *			to be valid for the duration of the negotiator.
+ * @param neg		The SDP negotiator instance.
+ * @param remote	The remote offer.
+ *
+ * @return		PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) 
+pjmedia_sdp_neg_set_remote_offer( pj_pool_t *pool,
+				  pjmedia_sdp_neg *neg,
+				  const pjmedia_sdp_session *remote);
+
+
+
+/**
+ * This function can only be called in PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER
+ * state, i.e. after application calls #pjmedia_sdp_neg_set_remote_offer()
+ * function. After this function is called, the negotiator state will
+ * move to PJMEDIA_SDP_NEG_STATE_WAIT_NEGO, and application can call the
+ * negotiation function #pjmedia_sdp_neg_negotiate().
+ *
+ * @param pool		Pool to allocate memory. The pool's lifetime needs
+ *			to be valid for the duration of the negotiator.
+ * @param neg		The SDP negotiator instance.
+ * @param local		Optional local answer. If negotiator has initial
+ *			local capability, application can specify NULL on
+ *			this argument; in this case, the negotiator will
+ *			create answer by by negotiating remote offer with
+ *			initial local capability. If negotiator doesn't have
+ *			initial local capability, application MUST specify
+ *			local answer here.
+ *
+ * @return		PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) 
+pjmedia_sdp_neg_set_local_answer( pj_pool_t *pool,
+				  pjmedia_sdp_neg *neg,
+				  const pjmedia_sdp_session *local);
+
+
+/**
+ * Call this function when the negotiator is in PJMEDIA_SDP_NEG_STATE_WAIT_NEGO
+ * state to see if it was local who is answering the offer (instead of
+ * remote).
+ *
+ * @param neg		The negotiator.
+ *
+ * @return		PJ_TRUE if it is local is answering an offer, PJ_FALSE
+ *			if remote has answered local offer.
+ */
+PJ_DECL(pj_bool_t) pjmedia_sdp_neg_has_local_answer(pjmedia_sdp_neg *neg);
+
+
+/**
+ * Cancel any pending offer, whether the offer is initiated by local or
+ * remote, and move negotiator state back to previous stable state
+ * (PJMEDIA_SDP_NEG_STATE_DONE). The negotiator must be in
+ * PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER or PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER
+ * state.
+ *
+ * @param neg		The negotiator.
+ *
+ * @return		PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_neg_cancel_offer(pjmedia_sdp_neg *neg);
+
+
+/**
+ * Negotiate local and remote answer. Before calling this function, the
+ * SDP negotiator must be in PJMEDIA_SDP_NEG_STATE_WAIT_NEGO state.
+ * After calling this function, the negotiator state will move to
+ * PJMEDIA_SDP_NEG_STATE_DONE regardless whether the negotiation has
+ * been successfull or not.
+ *
+ * If the negotiation succeeds (i.e. the return value is PJ_SUCCESS),
+ * the active local and remote SDP will be replaced with the new SDP
+ * from the negotiation process.
+ *
+ * If the negotiation fails, the active local and remote SDP will not
+ * change.
+ *
+ * @param pool		Pool to allocate memory. The pool's lifetime needs
+ *			to be valid for the duration of the negotiator.
+ * @param neg		The SDP negotiator instance.
+ * @param allow_asym	Should be zero.
+ *
+ * @return		PJ_SUCCESS when there is at least one media
+ *			is actuve common in both offer and answer, or 
+ *			failure code when negotiation has failed.
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_neg_negotiate( pj_pool_t *pool,
+					        pjmedia_sdp_neg *neg,
+						pj_bool_t allow_asym);
+
+
+/**
+ * Enumeration of customized SDP format matching option flags. See
+ * #pjmedia_sdp_neg_register_fmt_match_cb() for more info.
+ */
+typedef enum pjmedia_sdp_neg_fmt_match_flag
+{
+    /**
+     * In generating answer, the SDP fmtp in the answer candidate may need
+     * to be modified by the customized SDP format matching callback to
+     * achieve flexible SDP negotiation, e.g: AMR fmtp 'octet-align' field
+     * can be adjusted with the offer when the codec implementation support
+     * both packetization modes octet-aligned and bandwidth-efficient.
+     */
+    PJMEDIA_SDP_NEG_FMT_MATCH_ALLOW_MODIFY_ANSWER = 1,
+
+} pjmedia_sdp_neg_fmt_match_flag;
+
+
+/**
+ * The declaration of customized SDP format matching callback. See
+ * #pjmedia_sdp_neg_register_fmt_match_cb() for more info.
+ *
+ * @param pool		The memory pool.
+ * @param offer		The SDP media offer.
+ * @param o_fmt_idx	Index of the format in the SDP media offer.
+ * @param answer	The SDP media answer.
+ * @param a_fmt_idx	Index of the format in the SDP media answer.
+ * @param option	The format matching option, see
+ *			#pjmedia_sdp_neg_fmt_match_flag.
+ *
+ * @return		PJ_SUCCESS when the formats in offer and answer match.
+ */
+typedef pj_status_t (*pjmedia_sdp_neg_fmt_match_cb)(pj_pool_t *pool,
+						    pjmedia_sdp_media *offer,
+						    unsigned o_fmt_idx,
+						    pjmedia_sdp_media *answer,
+						    unsigned a_fmt_idx,
+						    unsigned option);
+
+
+/**
+ * Register customized SDP format matching callback function for the specified
+ * format. The customized SDP format matching is needed when the format
+ * identification in a media stream session cannot be simply determined by
+ * encoding name and clock rate, but also involves one or more format specific
+ * parameters, which are specified in SDP fmtp attribute. For example,
+ * an H.264 video stream is also identified by profile, level, and
+ * packetization-mode parameters. As those parameters are format specifics,
+ * the negotiation must be done by the format or codec implementation.
+ *
+ * To unregister the callback of specific format, just call this function with
+ * parameter #cb set to NULL.
+ *
+ * @param fmt_name	The format name, e.g: "H.264", "AMR", "G7221". Note
+ *			that the string buffer must remain valid until the
+ *			callback is unregistered.
+ * @param cb		The customized SDP format negotiation callback or
+ *			NULL to unregister the specified format callback.
+ *
+ * @return		PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_neg_register_fmt_match_cb(
+					const pj_str_t *fmt_name,
+					pjmedia_sdp_neg_fmt_match_cb cb);
+
+
+/**
+ * Match format in the SDP media offer and answer. The matching mechanism
+ * will be done by comparing the encoding name and clock rate, and if the
+ * custom format matching callback for the specified format is registered,
+ * see #pjmedia_sdp_neg_register_fmt_match_cb(), it will be called for more
+ * detail verification, e.g: format parameters specified in SDP fmtp.
+ *
+ * @param pool		The memory pool.
+ * @param offer		The SDP media offer.
+ * @param o_fmt_idx	Index of the format in the SDP media offer.
+ * @param answer	The SDP media answer.
+ * @param a_fmt_idx	Index of the format in the SDP media answer.
+ * @param option	The format matching option, see
+ *			#pjmedia_sdp_neg_fmt_match_flag.
+ *
+ * @return		PJ_SUCCESS when the formats in offer and answer match.
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_neg_fmt_match( pj_pool_t *pool,
+					        pjmedia_sdp_media *offer,
+					        unsigned o_fmt_idx,
+					        pjmedia_sdp_media *answer,
+					        unsigned a_fmt_idx,
+					        unsigned option);
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#endif	/* __PJMEDIA_SDP_NEG_H__ */
+