From eb24f7b8c23d894c75a173091c1cd25c897d3402 Mon Sep 17 00:00:00 2001 From: Benny Prijono Date: Wed, 3 Apr 2013 00:54:37 +0000 Subject: Fixed #1651: incoming CANCEL request is not reported in any callbacks git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@4455 74dad513-b988-da41-8d7b-12977e46ad98 --- pjsip/src/pjsip-ua/sip_inv.c | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) (limited to 'pjsip/src/pjsip-ua') diff --git a/pjsip/src/pjsip-ua/sip_inv.c b/pjsip/src/pjsip-ua/sip_inv.c index 35bb8fe8..d0fab9c9 100644 --- a/pjsip/src/pjsip-ua/sip_inv.c +++ b/pjsip/src/pjsip-ua/sip_inv.c @@ -623,9 +623,15 @@ static void mod_inv_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e) /* Call state handler for the invite session. */ (*inv_state_handler[inv->state])(inv, e); - /* Call on_tsx_state */ - if (mod_inv.cb.on_tsx_state_changed && inv->notify) + /* Call on_tsx_state. CANCEL request is a special case and has been + * reported earlier in inv_respond_incoming_cancel() + */ + if (mod_inv.cb.on_tsx_state_changed && inv->notify && + !(tsx->method.id==PJSIP_CANCEL_METHOD && + e->body.tsx_state.type==PJSIP_EVENT_RX_MSG)) + { (*mod_inv.cb.on_tsx_state_changed)(inv, tsx, e); + } /* Clear invite transaction when tsx is confirmed. * Previously we set invite_tsx to NULL only when transaction has @@ -2854,13 +2860,29 @@ on_error: */ static void inv_respond_incoming_cancel(pjsip_inv_session *inv, pjsip_transaction *cancel_tsx, - pjsip_rx_data *rdata) + pjsip_event *e) { pjsip_tx_data *tdata; pjsip_transaction *invite_tsx; + pjsip_rx_data *rdata; pj_str_t key; pj_status_t status; + pj_assert(e->body.tsx_state.type == PJSIP_EVENT_RX_MSG); + rdata = e->body.tsx_state.src.rdata; + + /* https://trac.pjsip.org/repos/ticket/1651 + * Special treatment for CANCEL. Since here we're responding to CANCEL + * automatically (including 487 to INVITE), application will see the + * 200/OK response to CANCEL first in the callback, and then 487 to + * INVITE, before the CANCEL request itself. And worse, pjsua application + * may not see the CANCEL request at all because by the time the CANCEL + * request is reported, call has been disconnected and further events + * from the INVITE session has been suppressed. + */ + if (mod_inv.cb.on_tsx_state_changed && inv->notify) + (*mod_inv.cb.on_tsx_state_changed)(inv, cancel_tsx, e); + /* See if we have matching INVITE server transaction: */ pjsip_tsx_create_key(rdata->tp_info.pool, &key, PJSIP_ROLE_UAS, @@ -3754,7 +3776,7 @@ static void inv_on_state_incoming( pjsip_inv_session *inv, pjsip_event *e) * Handle incoming CANCEL request. */ - inv_respond_incoming_cancel(inv, tsx, e->body.tsx_state.src.rdata); + inv_respond_incoming_cancel(inv, tsx, e); } } @@ -3878,7 +3900,7 @@ static void inv_on_state_early( pjsip_inv_session *inv, pjsip_event *e) * Handle incoming CANCEL request. */ - inv_respond_incoming_cancel(inv, tsx, e->body.tsx_state.src.rdata); + inv_respond_incoming_cancel(inv, tsx, e); } else if (tsx->role == PJSIP_ROLE_UAS && tsx->state == PJSIP_TSX_STATE_TRYING && -- cgit v1.2.3