/** 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;
}
return 0;
}
+static
int *u2s_alloc(su_home_t *home, int const *u2s)
{
if (u2s) {
}
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);
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,
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);
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;
+
+ 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;
- return soa_base_process_reject(ss, NULL);
+ 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)
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);
}