summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2010-06-23 12:21:20 +0000
committerBenny Prijono <bennylp@teluu.com>2010-06-23 12:21:20 +0000
commit6e609cb376bd29ad241c8bffd5571f0f98d128a7 (patch)
treee7e3552cc1afb636c9c37123c22e16f4fb36968a
parent0b4550b549b2dd9770c07aef9607ece8f122060a (diff)
Another unterminated SDP offer/answer negotiation fix (Re: #1045):
- fixed unterminated negotiation if our media transport rejects incoming offer (e.g. due to mismatch SRTP transport) with 488. - to fix the above, modified the SDP negotiator (sdp_neg.[hc])'s pjmedia_sdp_neg_cancel_offer() to also be able to cancel in remote offer state - also fixed the bug introduced previous Session Timer fix (Re: #1047), which cause SDP negotiator's state to be cleared after failed UAC UPDATE transaction is terminated, which means UPDATE can only be sent 5 seconds after the last UPDATE if the last UPDATE failed. git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@3217 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjmedia/include/pjmedia/sdp_neg.h8
-rw-r--r--pjmedia/src/pjmedia/sdp_neg.c3
-rw-r--r--pjsip/src/pjsip-ua/sip_inv.c17
3 files changed, 18 insertions, 10 deletions
diff --git a/pjmedia/include/pjmedia/sdp_neg.h b/pjmedia/include/pjmedia/sdp_neg.h
index 8ea61879..70bfccfa 100644
--- a/pjmedia/include/pjmedia/sdp_neg.h
+++ b/pjmedia/include/pjmedia/sdp_neg.h
@@ -622,9 +622,11 @@ PJ_DECL(pj_bool_t) pjmedia_sdp_neg_has_local_answer(pjmedia_sdp_neg *neg);
/**
- * Cancel previously sent offer, 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 state.
+ * 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.
*
diff --git a/pjmedia/src/pjmedia/sdp_neg.c b/pjmedia/src/pjmedia/sdp_neg.c
index 3e6039ec..974809d9 100644
--- a/pjmedia/src/pjmedia/sdp_neg.c
+++ b/pjmedia/src/pjmedia/sdp_neg.c
@@ -1390,7 +1390,8 @@ PJ_DEF(pj_status_t) pjmedia_sdp_neg_cancel_offer(pjmedia_sdp_neg *neg)
PJ_ASSERT_RETURN(neg, PJ_EINVAL);
/* Must be in LOCAL_OFFER state. */
- PJ_ASSERT_RETURN(neg->state == PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER,
+ PJ_ASSERT_RETURN(neg->state == PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER ||
+ neg->state == PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER,
PJMEDIA_SDPNEG_EINSTATE);
/* Reset state to done */
diff --git a/pjsip/src/pjsip-ua/sip_inv.c b/pjsip/src/pjsip-ua/sip_inv.c
index c58a92f7..dab68d4c 100644
--- a/pjsip/src/pjsip-ua/sip_inv.c
+++ b/pjsip/src/pjsip-ua/sip_inv.c
@@ -2789,7 +2789,14 @@ static void inv_respond_incoming_update(pjsip_inv_session *inv,
if (neg_state != PJMEDIA_SDP_NEG_STATE_WAIT_NEGO ||
(status=inv_negotiate_sdp(inv)) != PJ_SUCCESS)
{
- /* Negotiation has failed */
+ /* Negotiation has failed. If negotiator is still
+ * stuck at non-DONE state, cancel any ongoing offer.
+ */
+ neg_state = pjmedia_sdp_neg_get_state(inv->neg);
+ if (neg_state != PJMEDIA_SDP_NEG_STATE_DONE) {
+ pjmedia_sdp_neg_cancel_offer(inv->neg);
+ }
+
status = pjsip_dlg_create_response(inv->dlg, rdata,
PJSIP_SC_NOT_ACCEPTABLE_HERE,
NULL, &tdata);
@@ -2901,11 +2908,9 @@ static void inv_handle_update_response( pjsip_inv_session *inv,
}
}
- /* Otherwise if we don't get successful response, cancel
- * our negotiator.
- */
- if (status != PJ_SUCCESS &&
- pjmedia_sdp_neg_get_state(inv->neg)==PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER &&
+ /* Cancel the negotiation if we don't get successful negotiation by now */
+ if (pjmedia_sdp_neg_get_state(inv->neg) ==
+ PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER &&
tsx_inv_data && tsx_inv_data->sdp_done == PJ_FALSE)
{
pjmedia_sdp_neg_cancel_offer(inv->neg);