From 228747a48a41878ed2691c429ca6af90cadf8715 Mon Sep 17 00:00:00 2001 From: Liong Sauw Ming Date: Tue, 6 Dec 2016 07:29:11 +0000 Subject: Fixed #1982: Add option to reinitialize call media transports git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@5490 74dad513-b988-da41-8d7b-12977e46ad98 --- pjsip/include/pjsua-lib/pjsua.h | 15 ++++++++++++++- pjsip/src/pjsua-lib/pjsua_call.c | 9 +++++++-- pjsip/src/pjsua-lib/pjsua_media.c | 2 +- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h index af6bc3da..3702ab67 100644 --- a/pjsip/include/pjsua-lib/pjsua.h +++ b/pjsip/include/pjsua-lib/pjsua.h @@ -4284,7 +4284,20 @@ typedef enum pjsua_call_flag * #pjsua_call_update()/update2(). For re-invite/update, specifying * PJSUA_CALL_UNHOLD will take precedence over this flag. */ - PJSUA_CALL_NO_SDP_OFFER = 8 + PJSUA_CALL_NO_SDP_OFFER = 8, + + /** + * Deinitialize and recreate media, including media transport. This flag + * is useful in IP address change situation, if the media transport + * address (or address family) changes, for example during IPv4/IPv6 + * network handover. + * This flag is only valid for #pjsua_call_reinvite()/reinvite2(), or + * #pjsua_call_update()/update2(). + * + * Warning: If the re-INVITE/UPDATE fails, the old media will not be + * reverted. + */ + PJSUA_CALL_REINIT_MEDIA = 16 } pjsua_call_flag; diff --git a/pjsip/src/pjsua-lib/pjsua_call.c b/pjsip/src/pjsua-lib/pjsua_call.c index 45cf613a..2089fc16 100644 --- a/pjsip/src/pjsua-lib/pjsua_call.c +++ b/pjsip/src/pjsua-lib/pjsua_call.c @@ -569,7 +569,7 @@ on_error: static void cleanup_call_setting_flag(pjsua_call_setting *opt) { opt->flag &= ~(PJSUA_CALL_UNHOLD | PJSUA_CALL_UPDATE_CONTACT | - PJSUA_CALL_NO_SDP_OFFER); + PJSUA_CALL_NO_SDP_OFFER | PJSUA_CALL_REINIT_MEDIA); } @@ -608,12 +608,17 @@ static pj_status_t apply_call_setting(pjsua_call *call, call->opt = *opt; + if (call->opt.flag & PJSUA_CALL_REINIT_MEDIA) { + pjsua_media_channel_deinit(call->index); + } + /* If call is established or media channel hasn't been initialized, * reinit media channel. */ if ((call->inv && call->inv->state == PJSIP_INV_STATE_CONNECTING && call->med_cnt == 0) || - (call->inv && call->inv->state == PJSIP_INV_STATE_CONFIRMED)) + (call->inv && call->inv->state == PJSIP_INV_STATE_CONFIRMED) || + (call->opt.flag & PJSUA_CALL_REINIT_MEDIA)) { pjsip_role_e role = rem_sdp? PJSIP_ROLE_UAS : PJSIP_ROLE_UAC; pj_status_t status; diff --git a/pjsip/src/pjsua-lib/pjsua_media.c b/pjsip/src/pjsua-lib/pjsua_media.c index fe959907..68d466ff 100644 --- a/pjsip/src/pjsua-lib/pjsua_media.c +++ b/pjsip/src/pjsua-lib/pjsua_media.c @@ -1975,7 +1975,7 @@ pj_status_t pjsua_media_channel_init(pjsua_call_id call_id, * media from existing media. * Otherwise, apply media count from the call setting directly. */ - if (reinit) { + if (reinit && (call->opt.flag & PJSUA_CALL_REINIT_MEDIA) == 0) { /* We are sending reoffer, check media count for each media type * from the existing call media list. -- cgit v1.2.3