Module: sems Branch: master Commit: 2f36762bd9d5580eb162902242fdf4c4b0def739 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sems/?a=commit;h=2f36762bd9d5580eb162902242fdf4c4b0def739
Author: Stefan Sayer <[email protected]> Committer: Stefan Sayer <[email protected]> Date: Thu Sep 16 21:11:14 2010 +0200 UPDATE support for Session Timer - configured via app config file - so far only for one-legged calls (no sst_b2b support) --- core/AmSession.cpp | 31 +++++++++++++++++++- core/AmSession.h | 13 ++++++++- core/AmSipHeaders.h | 1 + core/plug-in/echo/etc/echo.conf | 20 ++++++++++++- core/plug-in/session_timer/SessionTimer.cpp | 41 ++++++++++++++++++++------ core/plug-in/session_timer/SessionTimer.h | 1 + 6 files changed, 94 insertions(+), 13 deletions(-) diff --git a/core/AmSession.cpp b/core/AmSession.cpp index 50fdf19..8b0a9a7 100644 --- a/core/AmSession.cpp +++ b/core/AmSession.cpp @@ -68,6 +68,7 @@ AmSession::AmSession() m_dtmfDetectionEnabled(true), accept_early_session(false), reliable_1xx(AmConfig::rel100), + refresh_method(REFRESH_UPDATE_FB_REINV), processing_status(SESSION_PROCESSING_EVENTS) #ifdef WITH_ZRTP , zrtp_session(NULL), zrtp_audio(NULL), enable_zrtp(true) @@ -682,6 +683,15 @@ void AmSession::onSipRequest(const AmSipRequest& req) CALL_EVENT_H(onSipRequest,req); DBG("onSipRequest: method = %s\n",req.method.c_str()); + + if (refresh_method == REFRESH_UPDATE_FB_REINV) { + if (key_in_list(getHeader(req.hdrs, SIP_HDR_ALLOW), + SIP_METH_UPDATE)) { + DBG("remote allows UPDATE, using UPDATE for session refresh.\n"); + refresh_method = REFRESH_UPDATE; + } + } + if(req.method == SIP_METH_INVITE){ switch(reliable_1xx) { @@ -774,6 +784,14 @@ void AmSession::onSipReply(const AmSipReply& reply, int old_dlg_status) { CALL_EVENT_H(onSipReply,reply,old_dlg_status); + if (refresh_method == REFRESH_UPDATE_FB_REINV) { + if (key_in_list(getHeader(reply.hdrs, SIP_HDR_ALLOW), + SIP_METH_UPDATE)) { + DBG("remote allows UPDATE, using UPDATE for session refresh.\n"); + refresh_method = REFRESH_UPDATE; + } + } + if (old_dlg_status != dlg.getStatus()) DBG("Dialog status changed %s -> %s (stopped=%s) \n", AmSipDialog::status2str[old_dlg_status], @@ -1081,7 +1099,18 @@ void AmSession::onRtpTimeout() setStopped(); } -void AmSession::sendUpdate(string &cont_type, string &body, string &hdrs) +void AmSession::refresh() { + if (refresh_method == REFRESH_UPDATE) { + DBG("Refreshing session with UPDATE\n"); + sendUpdate("", "", ""); + } else { + DBG("Refreshing session with re-INVITE\n"); + sendReinvite(true); + } +} + +void AmSession::sendUpdate(const string &cont_type, const string &body, + const string &hdrs) { dlg.update(cont_type, body, hdrs); } diff --git a/core/AmSession.h b/core/AmSession.h index 20c6d1f..620fe8c 100644 --- a/core/AmSession.h +++ b/core/AmSession.h @@ -164,6 +164,7 @@ protected: /** do accept early session? */ bool accept_early_session; + /** enable the reliability of provisional replies? */ unsigned char reliable_1xx; #define REL100_DISABLED 0 @@ -175,6 +176,13 @@ protected: public: + enum SessionRefreshMethod { + REFRESH_REINVITE = 0, // use reinvite + REFRESH_UPDATE, // use update + REFRESH_UPDATE_FB_REINV // use update or fallback to reinvite + }; + SessionRefreshMethod refresh_method; + AmRtpAudio* RTPStream(); #ifdef WITH_ZRTP @@ -347,8 +355,11 @@ public: bool force_symmetric_rtp, string* sdp_reply); + /** refresh the session - re-INVITE or UPDATE*/ + virtual void refresh(); + /** send an UPDATE in the session */ - virtual void sendUpdate(string &cont_type, string &body, string &hdrs); + virtual void sendUpdate(const string &cont_type, const string &body, const string &hdrs); /** send a Re-INVITE (if connected) */ virtual void sendReinvite(bool updateSDP = true, const string& headers = ""); diff --git a/core/AmSipHeaders.h b/core/AmSipHeaders.h index e8e4880..cdc3d31 100644 --- a/core/AmSipHeaders.h +++ b/core/AmSipHeaders.h @@ -30,6 +30,7 @@ #define SIP_HDR_PROXY_AUTHORIZATION "Proxy-Authorization" #define SIP_HDR_PROXY_AUTHENTICATE "Proxy-Authenticate" #define SIP_HDR_WWW_AUTHENTICATE "WWW-Authenticate" +#define SIP_HDR_ALLOW "Allow" #define SIP_HDR_COL(_hdr) _hdr ":" #define SIP_HDR_COLSP(_hdr) SIP_HDR_COL(_hdr) " " diff --git a/core/plug-in/echo/etc/echo.conf b/core/plug-in/echo/etc/echo.conf index 0f93230..b87edc4 100644 --- a/core/plug-in/echo/etc/echo.conf +++ b/core/plug-in/echo/etc/echo.conf @@ -1,7 +1,7 @@ # Echo plug-in configuration file # -# Session timer ([yes,no]; default: no) +# RFC4028 Session Timer ([yes,no]; default: no) # # - enables the session timer. @@ -15,3 +15,21 @@ # - set the "Min-SE" parameter for the session timer. # # minimum_timer=90 + +# session refresh (Session Timer, RFC4028) method +# +# INVITE - use re-INVITE +# UPDATE - use UPDATE +# UPDATE_FALLBACK_INVITE - use UPDATE if indicated in Allow, re-INVITE otherwise +# +# Default: UPDATE_FALLBACK_INVITE +# +# Note: Session Timers are only supported in some applications +# +#session_refresh_method=UPDATE + +# accept_501_reply - accept 501 reply as successful refresh? [yes|no] +# +# Default: yes +# +#accept_501_reply=no diff --git a/core/plug-in/session_timer/SessionTimer.cpp b/core/plug-in/session_timer/SessionTimer.cpp index 6c35f11..e36dd48 100644 --- a/core/plug-in/session_timer/SessionTimer.cpp +++ b/core/plug-in/session_timer/SessionTimer.cpp @@ -53,8 +53,10 @@ SessionTimer::SessionTimer(AmSession* s) :AmSessionEventHandler(), s(s), session_interval(0), - session_refresher(refresh_remote) -{} + session_refresher(refresh_remote), + accept_501_reply(true) +{ +} bool SessionTimer::process(AmEvent* ev) { @@ -140,6 +142,24 @@ int SessionTimer::configure(AmConfigReader& conf) session_timer_conf.getMinimumTimer() ); + if (conf.hasParameter("session_refresh_method")) { + string refresh_method_s = conf.getParameter("session_refresh_method"); + if (refresh_method_s == "UPDATE") { + s->refresh_method = AmSession::REFRESH_UPDATE; + } else if (refresh_method_s == "UPDATE_FALLBACK_INVITE") { + s->refresh_method = AmSession::REFRESH_UPDATE_FB_REINV; + } else if (refresh_method_s == "INVITE") { + s->refresh_method = AmSession::REFRESH_REINVITE; + } else { + ERROR("unknown setting for 'session_refresh_method' config option.\n"); + return -1; + } + DBG("set session refresh method: %d.\n", s->refresh_method); + } + + if (conf.getParameter("accept_501_reply")=="no") + accept_501_reply = false; + return 0; } @@ -253,8 +273,9 @@ void SessionTimer::updateTimer(AmSession* s, const AmSipReply& reply) if (!session_timer_conf.getEnableSessionTimer()) return; - // only update timer on positive reply - if ((reply.code < 200) || (reply.code >= 300)) + // only update timer on positive reply, or 501 if config'd + if (((reply.code < 200) || (reply.code >= 300)) && + (!(accept_501_reply && reply.code == 501))) return; // determine session interval @@ -319,12 +340,12 @@ void SessionTimer::onTimeoutEvent(AmTimeoutEvent* timeout_ev) int timer_id = timeout_ev->data.get(0).asInt(); if (timer_id == ID_SESSION_REFRESH_TIMER) { - DBG("Session Timer: initiating refresh (Re-Invite)\n"); - if (session_refresher == refresh_local) - // send reinvite with SDP - s->sendReinvite(true); - else - WARN("need session refresh but remote session is refresher\n"); + if (session_refresher == refresh_local) { + DBG("Session Timer: initiating session refresh\n"); + s->refresh(); + } else { + DBG("need session refresh but remote session is refresher\n"); + } } else if (timer_id == ID_SESSION_INTERVAL_TIMER) { // // let the session know it got timeout // onTimeout(); diff --git a/core/plug-in/session_timer/SessionTimer.h b/core/plug-in/session_timer/SessionTimer.h index 1ca75f9..0b179e8 100644 --- a/core/plug-in/session_timer/SessionTimer.h +++ b/core/plug-in/session_timer/SessionTimer.h @@ -114,6 +114,7 @@ class SessionTimer: public AmSessionEventHandler unsigned int session_interval; SessionRefresher session_refresher; SessionRefresherRole session_refresher_role; + bool accept_501_reply; void updateTimer(AmSession* s,const AmSipRequest& req); void updateTimer(AmSession* s,const AmSipReply& reply); _______________________________________________ Semsdev mailing list [email protected] http://lists.iptel.org/mailman/listinfo/semsdev
