blob: 3f6eb319202c48b8e7fe1bfc96e54673be77fae2 [file] [log] [blame]
/* $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);
/**
* 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__ */