UPDATE support for Session Timer

- configured via app config file
- so far only for one-legged calls (no sst_b2b support)
sayer/1.4-spce2.6
Stefan Sayer 16 years ago
parent 6e503d4112
commit 2f36762bd9

@ -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);
}

@ -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 = "");

@ -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) " "

@ -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

@ -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();

@ -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);

Loading…
Cancel
Save