From 10c67f82197ef61cb1a1d547c46ada7aea5cda3f Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Wed, 11 Feb 2009 17:07:59 +0000 Subject: [PATCH] Fri Jan 16 13:27:39 CST 2009 Pekka Pessi * soa: fixed restoring state after failed offer git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@11835 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- libs/sofia-sip/.update | 2 +- libs/sofia-sip/libsofia-sip-ua/soa/soa.c | 9 +-- .../libsofia-sip-ua/soa/soa_static.c | 60 +++++++++++++++---- 3 files changed, 52 insertions(+), 19 deletions(-) diff --git a/libs/sofia-sip/.update b/libs/sofia-sip/.update index 37ad46c796..4f2f64fd5d 100644 --- a/libs/sofia-sip/.update +++ b/libs/sofia-sip/.update @@ -1 +1 @@ -Wed Feb 11 11:06:56 CST 2009 +Wed Feb 11 11:07:52 CST 2009 diff --git a/libs/sofia-sip/libsofia-sip-ua/soa/soa.c b/libs/sofia-sip/libsofia-sip-ua/soa/soa.c index eb45c9cadf..77f1ab6a46 100644 --- a/libs/sofia-sip/libsofia-sip-ua/soa/soa.c +++ b/libs/sofia-sip/libsofia-sip-ua/soa/soa.c @@ -938,7 +938,7 @@ soa_base_set_capability_sdp(soa_session_t *ss, * * User SDP is used as basis for SDP Offer/Answer negotiation. It can * be very minimal template, consisting just m= line containing media name, - * transport protocol port number and list of supported codecs. + * transport protocol, port number and list of supported codecs. * * The SDP used as an offer or answer (generated by soa_generate_answer() or * soa_generate_offer()) is known as local SDP and it is available @@ -1703,13 +1703,10 @@ int soa_base_process_reject(soa_session_t *ss, (void)completed; - if (!l_sdp) - return -1; - - soa_set_activity(ss, l_sdp->sdp_media, soa_activity_session); - ss->ss_offer_sent = 0; + soa_set_activity(ss, l_sdp ? l_sdp->sdp_media : NULL, soa_activity_session); + return 0; } diff --git a/libs/sofia-sip/libsofia-sip-ua/soa/soa_static.c b/libs/sofia-sip/libsofia-sip-ua/soa/soa_static.c index 60e78e77db..2210d49760 100644 --- a/libs/sofia-sip/libsofia-sip-ua/soa/soa_static.c +++ b/libs/sofia-sip/libsofia-sip-ua/soa/soa_static.c @@ -84,6 +84,11 @@ typedef struct soa_static_session /** Mapping from session SDP m= lines to user SDP m= lines */ int *sss_s2u; + /** State kept from SDP before current offer */ + struct { + int *u2s, *s2u; + } sss_previous; + /** Our latest offer or answer */ sdp_session_t *sss_latest; } @@ -886,6 +891,7 @@ int soa_sdp_upgrade(soa_session_t *ss, return 0; } +static int *u2s_alloc(su_home_t *home, int const *u2s) { if (u2s) { @@ -1318,6 +1324,8 @@ static int offer_answer_step(soa_session_t *ss, } soa_description_free(ss, ss->ss_previous); + su_free(ss->ss_home, sss->sss_previous.u2s), sss->sss_previous.u2s = NULL; + su_free(ss->ss_home, sss->sss_previous.s2u), sss->sss_previous.s2u = NULL; if (u2s) { u2s = u2s_alloc(ss->ss_home, u2s); @@ -1358,10 +1366,18 @@ static int offer_answer_step(soa_session_t *ss, if (action == generate_offer) { /* Keep a copy of previous session state */ + int *previous_u2s = u2s_alloc(ss->ss_home, sss->sss_u2s); + int *previous_s2u = u2s_alloc(ss->ss_home, sss->sss_s2u); + + if ((sss->sss_u2s && !previous_u2s) || (sss->sss_s2u && !previous_s2u)) + goto internal_error; + *ss->ss_previous = *ss->ss_local; memset(ss->ss_local, 0, (sizeof *ss->ss_local)); ss->ss_previous_user_version = ss->ss_local_user_version; ss->ss_previous_remote_version = ss->ss_local_remote_version; + sss->sss_previous.u2s = previous_u2s; + sss->sss_previous.s2u = previous_s2u; } SU_DEBUG_7(("soa_static(%p, %s): %s\n", (void *)ss, by, @@ -1374,6 +1390,8 @@ static int offer_answer_step(soa_session_t *ss, memset(ss->ss_previous, 0, (sizeof *ss->ss_previous)); ss->ss_previous_user_version = 0; ss->ss_previous_remote_version = 0; + su_free(ss->ss_home, sss->sss_previous.u2s), sss->sss_previous.u2s = NULL; + su_free(ss->ss_home, sss->sss_previous.s2u), sss->sss_previous.s2u = NULL; } su_free(ss->ss_home, u2s), su_free(ss->ss_home, s2u); @@ -1467,21 +1485,26 @@ static int soa_static_process_answer(soa_session_t *ss, static int soa_static_process_reject(soa_session_t *ss, soa_callback_f *completed) { + soa_static_session_t *sss = (soa_static_session_t *)ss; struct soa_description d[1]; - if (ss->ss_previous_user_version) { - *d = *ss->ss_local; - *ss->ss_local = *ss->ss_previous; - ss->ss_local_user_version = ss->ss_previous_user_version; - ss->ss_local_remote_version = ss->ss_previous_remote_version; + soa_base_process_reject(ss, NULL); - memset(ss->ss_previous, 0, (sizeof *ss->ss_previous)); - soa_description_free(ss, d); - ss->ss_previous_user_version = 0; - ss->ss_previous_remote_version = 0; - } + *d = *ss->ss_local; + *ss->ss_local = *ss->ss_previous; + ss->ss_local_user_version = ss->ss_previous_user_version; + ss->ss_local_remote_version = ss->ss_previous_remote_version; - return soa_base_process_reject(ss, NULL); + memset(ss->ss_previous, 0, (sizeof *ss->ss_previous)); + soa_description_free(ss, d); + su_free(ss->ss_home, sss->sss_previous.u2s), sss->sss_previous.u2s = NULL; + su_free(ss->ss_home, sss->sss_previous.s2u), sss->sss_previous.s2u = NULL; + ss->ss_previous_user_version = 0; + ss->ss_previous_remote_version = 0; + + su_free(ss->ss_home, sss->sss_latest), sss->sss_latest = NULL; + + return 0; } static int soa_static_activate(soa_session_t *ss, char const *option) @@ -1496,6 +1519,19 @@ static int soa_static_deactivate(soa_session_t *ss, char const *option) static void soa_static_terminate(soa_session_t *ss, char const *option) { - soa_description_free(ss, ss->ss_user); + soa_static_session_t *sss = (soa_static_session_t *)ss; + + soa_description_free(ss, ss->ss_local); + su_free(ss->ss_home, sss->sss_u2s), sss->sss_u2s = NULL; + su_free(ss->ss_home, sss->sss_s2u), sss->sss_s2u = NULL; + + soa_description_free(ss, ss->ss_previous); + ss->ss_previous_user_version = 0; + ss->ss_previous_remote_version = 0; + su_free(ss->ss_home, sss->sss_previous.u2s), sss->sss_previous.u2s = NULL; + su_free(ss->ss_home, sss->sss_previous.s2u), sss->sss_previous.s2u = NULL; + + su_free(ss->ss_home, sss->sss_latest), sss->sss_latest = NULL; + soa_base_terminate(ss, option); }