WARNING: The online documentation has moved to https://docs.pjsip.org.

Visit the new documentation at https://docs.pjsip.org:

BLOG | DOCUMENTATION | GITHUB

Home --> Documentations --> PJMEDIA Reference

SDP Negotiation State Machine (Offer/Answer Model, RFC 3264)

SDP Negotiation State Machine (Offer/Answer Model, RFC 3264) More...

Typedefs

typedef enum pjmedia_sdp_neg_state pjmedia_sdp_neg_state
 
typedef struct pjmedia_sdp_neg pjmedia_sdp_neg
 
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)
 

Enumerations

enum  pjmedia_sdp_neg_state {
  PJMEDIA_SDP_NEG_STATE_NULL ,
  PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER ,
  PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER ,
  PJMEDIA_SDP_NEG_STATE_WAIT_NEGO ,
  PJMEDIA_SDP_NEG_STATE_DONE
}
 
enum  pjmedia_mod_offer_flag { PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE = 1 }
 
enum  pjmedia_sdp_neg_fmt_match_flag { PJMEDIA_SDP_NEG_FMT_MATCH_ALLOW_MODIFY_ANSWER = 1 }
 

Functions

const char * pjmedia_sdp_neg_state_str (pjmedia_sdp_neg_state state)
 
pj_status_t pjmedia_sdp_neg_create_w_local_offer (pj_pool_t *pool, const pjmedia_sdp_session *local, pjmedia_sdp_neg **p_neg)
 
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)
 
pj_status_t pjmedia_sdp_neg_set_prefer_remote_codec_order (pjmedia_sdp_neg *neg, pj_bool_t prefer_remote)
 
pj_status_t pjmedia_sdp_neg_set_answer_multiple_codecs (pjmedia_sdp_neg *neg, pj_bool_t answer_multiple)
 
pjmedia_sdp_neg_state pjmedia_sdp_neg_get_state (pjmedia_sdp_neg *neg)
 
pj_status_t pjmedia_sdp_neg_get_active_local (pjmedia_sdp_neg *neg, const pjmedia_sdp_session **local)
 
pj_status_t pjmedia_sdp_neg_get_active_remote (pjmedia_sdp_neg *neg, const pjmedia_sdp_session **remote)
 
pj_bool_t pjmedia_sdp_neg_was_answer_remote (pjmedia_sdp_neg *neg)
 
pj_status_t pjmedia_sdp_neg_get_neg_remote (pjmedia_sdp_neg *neg, const pjmedia_sdp_session **remote)
 
pj_status_t pjmedia_sdp_neg_get_neg_local (pjmedia_sdp_neg *neg, const pjmedia_sdp_session **local)
 
pj_status_t pjmedia_sdp_neg_modify_local_offer (pj_pool_t *pool, pjmedia_sdp_neg *neg, const pjmedia_sdp_session *local)
 
pj_status_t pjmedia_sdp_neg_modify_local_offer2 (pj_pool_t *pool, pjmedia_sdp_neg *neg, unsigned flags, const pjmedia_sdp_session *local)
 
pj_status_t pjmedia_sdp_neg_send_local_offer (pj_pool_t *pool, pjmedia_sdp_neg *neg, const pjmedia_sdp_session **offer)
 
pj_status_t pjmedia_sdp_neg_set_remote_answer (pj_pool_t *pool, pjmedia_sdp_neg *neg, const pjmedia_sdp_session *remote)
 
pj_status_t pjmedia_sdp_neg_set_remote_offer (pj_pool_t *pool, pjmedia_sdp_neg *neg, const pjmedia_sdp_session *remote)
 
pj_status_t pjmedia_sdp_neg_set_local_answer (pj_pool_t *pool, pjmedia_sdp_neg *neg, const pjmedia_sdp_session *local)
 
pj_bool_t pjmedia_sdp_neg_has_local_answer (pjmedia_sdp_neg *neg)
 
pj_status_t pjmedia_sdp_neg_cancel_offer (pjmedia_sdp_neg *neg)
 
pj_status_t pjmedia_sdp_neg_negotiate (pj_pool_t *pool, pjmedia_sdp_neg *neg, pj_bool_t allow_asym)
 
pj_status_t pjmedia_sdp_neg_register_fmt_match_cb (const pj_str_t *fmt_name, pjmedia_sdp_neg_fmt_match_cb cb)
 
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)
 

Detailed Description

The header file <pjmedia/sdp_neg.h> contains the declaration of SDP offer and answer negotiator. SDP offer and answer model is described in RFC 3264 "An Offer/Answer Model with Session Description Protocol (SDP)".

The SDP negotiator is represented with opaque type pjmedia_sdp_neg. This structure contains negotiation state and several SDP session descriptors currently being used in the negotiation.

SDP Negotiator State Diagram

The following diagram describes the state transition diagram of the SDP negotiator.


                                             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() +--------------+

SDP Offer/Answer Model with Negotiator

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.

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.

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 Generating SDP Answer describes the case when application is ready to create a SDP answer.

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).

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 sendrecv, while the answer specifies that remote stream is inactive. In this case, the negotiator will update the stream in the local active media as 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.

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:

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.

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.

Typedef Documentation

◆ pjmedia_sdp_neg_state

◆ pjmedia_sdp_neg

Opaque declaration of SDP negotiator.

◆ pjmedia_sdp_neg_fmt_match_cb

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)

The declaration of customized SDP format matching callback. See pjmedia_sdp_neg_register_fmt_match_cb() for more info.

Parameters
poolThe memory pool.
offerThe SDP media offer.
o_fmt_idxIndex of the format in the SDP media offer.
answerThe SDP media answer.
a_fmt_idxIndex of the format in the SDP media answer.
optionThe format matching option, see pjmedia_sdp_neg_fmt_match_flag.
Returns
PJ_SUCCESS when the formats in offer and answer match.

Enumeration Type Documentation

◆ pjmedia_sdp_neg_state

This enumeration describes SDP negotiation state.

Enumerator
PJMEDIA_SDP_NEG_STATE_NULL 

This is the state of SDP negoator before it is initialized.

PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER 

This state occurs when SDP negotiator has sent our offer to remote and it is waiting for answer.

PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER 

This state occurs when SDP negotiator has received offer from remote and currently waiting for local answer.

PJMEDIA_SDP_NEG_STATE_WAIT_NEGO 

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_DONE 

This state occurs when SDP negotiation has completed, either successfully or not.

◆ pjmedia_mod_offer_flag

Flags to be given to pjmedia_sdp_neg_modify_local_offer2().

Enumerator
PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE 

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_fmt_match_flag

Enumeration of customized SDP format matching option flags. See pjmedia_sdp_neg_register_fmt_match_cb() for more info.

Enumerator
PJMEDIA_SDP_NEG_FMT_MATCH_ALLOW_MODIFY_ANSWER 

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.

Function Documentation

◆ pjmedia_sdp_neg_state_str()

const char * pjmedia_sdp_neg_state_str ( pjmedia_sdp_neg_state  state)

Get the state string description of the specified state.

Parameters
stateNegotiator state.
Returns
String description of the state.

◆ pjmedia_sdp_neg_create_w_local_offer()

pj_status_t pjmedia_sdp_neg_create_w_local_offer ( pj_pool_t pool,
const pjmedia_sdp_session local,
pjmedia_sdp_neg **  p_neg 
)

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.

Parameters
poolPool to allocate memory. The pool's lifetime needs to be valid for the duration of the negotiator.
localThe initial local capability.
p_negPointer to receive the negotiator instance.
Returns
PJ_SUCCESS on success, or the appropriate error code.

◆ pjmedia_sdp_neg_create_w_remote_offer()

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 
)

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.

Parameters
poolPool to allocate memory. The pool's lifetime needs to be valid for the duration of the negotiator.
initialOptional initial local capability.
remoteThe remote offer.
p_negPointer to receive the negotiator instance.
Returns
PJ_SUCCESS on success, or the appropriate error code.

◆ pjmedia_sdp_neg_set_prefer_remote_codec_order()

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 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.

Parameters
negThe SDP negotiator instance.
prefer_remoteIf 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.

◆ pjmedia_sdp_neg_set_answer_multiple_codecs()

pj_status_t pjmedia_sdp_neg_set_answer_multiple_codecs ( pjmedia_sdp_neg neg,
pj_bool_t  answer_multiple 
)

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.

Parameters
negThe SDP negotiator instance.
answer_multipleIf non-zero, the negotiator will respond with multiple formats. If zero only a single format will be returned.

◆ pjmedia_sdp_neg_get_state()

pjmedia_sdp_neg_state pjmedia_sdp_neg_get_state ( pjmedia_sdp_neg neg)

Get SDP negotiator state.

Parameters
negThe SDP negotiator instance.
Returns
The negotiator state.

◆ pjmedia_sdp_neg_get_active_local()

pj_status_t pjmedia_sdp_neg_get_active_local ( pjmedia_sdp_neg neg,
const pjmedia_sdp_session **  local 
)

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.

Parameters
negThe SDP negotiator instance.
localPointer to receive the local active SDP.
Returns
PJ_SUCCESS if local active SDP is present.

◆ pjmedia_sdp_neg_get_active_remote()

pj_status_t pjmedia_sdp_neg_get_active_remote ( pjmedia_sdp_neg neg,
const pjmedia_sdp_session **  remote 
)

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.

Parameters
negThe SDP negotiator instance.
remotePointer to receive the remote active SDP.
Returns
PJ_SUCCESS if remote active SDP is present.

◆ pjmedia_sdp_neg_was_answer_remote()

pj_bool_t pjmedia_sdp_neg_was_answer_remote ( pjmedia_sdp_neg neg)

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.

Parameters
negThe SDP negotiator instance.
Returns
Non-zero if it was remote who sent answer, otherwise zero if it was local who supplied answer.

◆ pjmedia_sdp_neg_get_neg_remote()

pj_status_t pjmedia_sdp_neg_get_neg_remote ( pjmedia_sdp_neg neg,
const pjmedia_sdp_session **  remote 
)

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.

Parameters
negThe SDP negotiator instance.
remotePointer to receive the current remote offer or answer.
Returns
PJ_SUCCESS if the negotiator currently has remote offer or answer.

◆ pjmedia_sdp_neg_get_neg_local()

pj_status_t pjmedia_sdp_neg_get_neg_local ( pjmedia_sdp_neg neg,
const pjmedia_sdp_session **  local 
)

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.

Parameters
negThe SDP negotiator instance.
localPointer to receive the current local offer or answer.
Returns
PJ_SUCCESS if the negotiator currently has local offer or answer.

◆ pjmedia_sdp_neg_modify_local_offer()

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. See also pjmedia_sdp_neg_modify_local_offer2()

Parameters
poolPool to allocate memory. The pool's lifetime needs to be valid for the duration of the negotiator.
negThe SDP negotiator instance.
localThe new local SDP.
Returns
PJ_SUCCESS on success, or the appropriate error code.

◆ pjmedia_sdp_neg_modify_local_offer2()

pj_status_t pjmedia_sdp_neg_modify_local_offer2 ( pj_pool_t pool,
pjmedia_sdp_neg neg,
unsigned  flags,
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.

Parameters
poolPool to allocate memory. The pool's lifetime needs to be valid for the duration of the negotiator.
negThe SDP negotiator instance.
flagsBitmask from pjmedia_mod_offer_flag.
localThe new local SDP.
Returns
PJ_SUCCESS on success, or the appropriate error code.

◆ pjmedia_sdp_neg_send_local_offer()

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_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().

Parameters
poolPool to allocate memory. The pool's lifetime needs to be valid for the duration of the negotiator.
negThe SDP negotiator instance.
offerPointer to receive active local SDP to be offered to remote.
Returns
PJ_SUCCESS if local offer can be created.

◆ pjmedia_sdp_neg_set_remote_answer()

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_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().

Parameters
poolPool to allocate memory. The pool's lifetime needs to be valid for the duration of the negotiator.
negThe SDP negotiator instance.
remoteThe remote answer.
Returns
PJ_SUCCESS on success.

◆ pjmedia_sdp_neg_set_remote_offer()

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_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.

Parameters
poolPool to allocate memory. The pool's lifetime needs to be valid for the duration of the negotiator.
negThe SDP negotiator instance.
remoteThe remote offer.
Returns
PJ_SUCCESS on success.

◆ pjmedia_sdp_neg_set_local_answer()

pj_status_t pjmedia_sdp_neg_set_local_answer ( pj_pool_t pool,
pjmedia_sdp_neg neg,
const pjmedia_sdp_session local 
)

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().

Parameters
poolPool to allocate memory. The pool's lifetime needs to be valid for the duration of the negotiator.
negThe SDP negotiator instance.
localOptional 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.
Returns
PJ_SUCCESS on success.

◆ pjmedia_sdp_neg_has_local_answer()

pj_bool_t pjmedia_sdp_neg_has_local_answer ( pjmedia_sdp_neg neg)

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).

Parameters
negThe negotiator.
Returns
PJ_TRUE if it is local is answering an offer, PJ_FALSE if remote has answered local offer.

◆ pjmedia_sdp_neg_cancel_offer()

pj_status_t pjmedia_sdp_neg_cancel_offer ( 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.

Parameters
negThe negotiator.
Returns
PJ_SUCCESS or the appropriate error code.

◆ pjmedia_sdp_neg_negotiate()

pj_status_t pjmedia_sdp_neg_negotiate ( pj_pool_t pool,
pjmedia_sdp_neg neg,
pj_bool_t  allow_asym 
)

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.

Parameters
poolPool to allocate memory. The pool's lifetime needs to be valid for the duration of the negotiator.
negThe SDP negotiator instance.
allow_asymShould be zero.
Returns
PJ_SUCCESS when there is at least one media is actuve common in both offer and answer, or failure code when negotiation has failed.

◆ pjmedia_sdp_neg_register_fmt_match_cb()

pj_status_t pjmedia_sdp_neg_register_fmt_match_cb ( const pj_str_t fmt_name,
pjmedia_sdp_neg_fmt_match_cb  cb 
)

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.

Parameters
fmt_nameThe format name, e.g: "H.264", "AMR", "G7221". Note that the string buffer must remain valid until the callback is unregistered.
cbThe customized SDP format negotiation callback or NULL to unregister the specified format callback.
Returns
PJ_SUCCESS on success.

◆ pjmedia_sdp_neg_fmt_match()

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 
)

Match format in the SDP media offer and answer. The matching mechanism will be done by comparing the encoding name, clock rate, and encoding parameters (if any), 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.

Parameters
poolThe memory pool.
offerThe SDP media offer.
o_fmt_idxIndex of the format in the SDP media offer.
answerThe SDP media answer.
a_fmt_idxIndex of the format in the SDP media answer.
optionThe format matching option, see pjmedia_sdp_neg_fmt_match_flag.
Returns
PJ_SUCCESS when the formats in offer and answer match.

References PJ_END_DECL.

 


PJMEDIA small footprint Open Source media stack
Copyright (C) 2006-2008 Teluu Inc.