From f49a5d7f747b652ea87621962e94be22db1605e5 Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Tue, 30 Jun 2009 14:16:05 +0000 Subject: [PATCH] - simplified session timer config - moved session timer config into session timer module. git-svn-id: http://svn.berlios.de/svnroot/repos/sems/trunk@1438 8eb893ce-cfd4-0310-b710-fb5ebe64c474 --- core/AmApi.cpp | 4 +- core/AmApi.h | 3 +- core/AmConfig.cpp | 69 +---------- core/AmConfig.h | 35 ------ core/AmConfigReader.cpp | 3 +- core/AmSessionEventHandler.cpp | 5 + core/AmSessionEventHandler.h | 7 ++ core/plug-in/echo/Echo.cpp | 40 ++++++- core/plug-in/echo/Echo.h | 4 + core/plug-in/session_timer/SessionTimer.cpp | 122 +++++++++++++++----- core/plug-in/session_timer/SessionTimer.h | 45 +++++++- core/sems.h | 5 - 12 files changed, 191 insertions(+), 151 deletions(-) diff --git a/core/AmApi.cpp b/core/AmApi.cpp index ce818e56..a48712ca 100644 --- a/core/AmApi.cpp +++ b/core/AmApi.cpp @@ -44,7 +44,7 @@ AmDynInvokeFactory::AmDynInvokeFactory(const string& name) } AmSessionFactory::AmSessionFactory(const string& name) - : AmPluginFactory(name), mod_conf(AmConfig::defaultSessionTimerConfig) + : AmPluginFactory(name) { } @@ -67,7 +67,7 @@ AmSession* AmSessionFactory::onRefer(const AmSipRequest& req, } int AmSessionFactory::configureModule(AmConfigReader& cfg) { - return mod_conf.readFromConfig(cfg); + return 0;//mod_conf.readFromConfig(cfg); } void AmSessionFactory::configureSession(AmSession* sess) { diff --git a/core/AmApi.h b/core/AmApi.h index 3e476caa..fafaeba4 100644 --- a/core/AmApi.h +++ b/core/AmApi.h @@ -32,6 +32,7 @@ #include "AmThread.h" #include "AmSipMsg.h" #include "AmConfig.h" +#include "AmConfigReader.h" #include "AmArg.h" #include "AmEventQueue.h" @@ -119,8 +120,6 @@ class AmSessionEventHandlerFactory: public AmPluginFactory class AmSessionFactory: public AmPluginFactory { - AmSessionTimerConfig mod_conf; - protected: /** * This reads the module configuration from diff --git a/core/AmConfig.cpp b/core/AmConfig.cpp index 8b03b5a4..c03d1545 100644 --- a/core/AmConfig.cpp +++ b/core/AmConfig.cpp @@ -75,8 +75,6 @@ Dtmf::InbandDetectorType AmConfig::DefaultDTMFDetector = Dtmf::SEMSInternal; bool AmConfig::IgnoreSIGCHLD = true; -AmSessionTimerConfig AmConfig::defaultSessionTimerConfig; - int AmConfig::setSIPPort(const string& port) { if(sscanf(port.c_str(),"%u",&AmConfig::LocalSIPPort) != 1) { @@ -368,7 +366,7 @@ int AmConfig::readConfiguration() } } - return defaultSessionTimerConfig.readFromConfig(cfg); + return 0; } int AmConfig::init() @@ -376,68 +374,3 @@ int AmConfig::init() return 0; } -AmSessionTimerConfig::AmSessionTimerConfig() - : EnableSessionTimer(DEFAULT_ENABLE_SESSION_TIMER), - SessionExpires(SESSION_EXPIRES), - MinimumTimer(MINIMUM_TIMER) -{ - -} -AmSessionTimerConfig::~AmSessionTimerConfig() -{ -} - -int AmSessionTimerConfig::readFromConfig(AmConfigReader& cfg) -{ - // enable_session_timer - if(cfg.hasParameter("enable_session_timer")){ - if(!setEnableSessionTimer(cfg.getParameter("enable_session_timer"))){ - ERROR("invalid enable_session_timer specified\n"); - return -1; - } - } - - // session_expires - if(cfg.hasParameter("session_expires")){ - if(!setSessionExpires(cfg.getParameter("session_expires"))){ - ERROR("invalid session_expires specified\n"); - return -1; - } - } - - // minimum_timer - if(cfg.hasParameter("minimum_timer")){ - if(!setMinimumTimer(cfg.getParameter("minimum_timer"))){ - ERROR("invalid minimum_timer specified\n"); - return -1; - } - } - return 0; -} - -int AmSessionTimerConfig::setEnableSessionTimer(const string& enable) { - if ( strcasecmp(enable.c_str(), "yes") == 0 ) { - EnableSessionTimer = 1; - } else if ( strcasecmp(enable.c_str(), "no") == 0 ) { - EnableSessionTimer = 0; - } else { - return 0; - } - return 1; -} - -int AmSessionTimerConfig::setSessionExpires(const string& se) { - if(sscanf(se.c_str(),"%u",&SessionExpires) != 1) { - return 0; - } - DBG("setSessionExpires(%i)\n",SessionExpires); - return 1; -} - -int AmSessionTimerConfig::setMinimumTimer(const string& minse) { - if(sscanf(minse.c_str(),"%u",&MinimumTimer) != 1) { - return 0; - } - DBG("setMinimumTimer(%i)\n",MinimumTimer); - return 1; -} diff --git a/core/AmConfig.h b/core/AmConfig.h index a7d50e51..9388542b 100644 --- a/core/AmConfig.h +++ b/core/AmConfig.h @@ -38,7 +38,6 @@ using std::string; #include #include -class AmSessionTimerConfig; /** * \brief holds the current configuration. @@ -76,8 +75,6 @@ struct AmConfig static int RtpLowPort; /** Highest local RTP port */ static int RtpHighPort; - /* Session Timer: */ - static AmSessionTimerConfig defaultSessionTimerConfig; /** number of session scheduler threads */ static int MediaProcessorThreads; /** the interface SIP requests are sent from - needed for registrar_client */ @@ -156,38 +153,6 @@ struct AmConfig static int setDeadRtpTime(const string& drt); }; -class AmConfigReader; -/** \brief config for the session timer */ -class AmSessionTimerConfig { - /** Session Timer: enable? */ - int EnableSessionTimer; - /** Session Timer: Desired Session-Expires */ - unsigned int SessionExpires; - /** Session Timer: Minimum Session-Expires */ - unsigned int MinimumTimer; - -public: - AmSessionTimerConfig(); - ~AmSessionTimerConfig(); - - - /** Session Timer: Enable Session Timer? - returns 0 on invalid value */ - int setEnableSessionTimer(const string& enable); - /** Session Timer: Setter for Desired Session-Expires, - returns 0 on invalid value */ - int setSessionExpires(const string& se); - /** Session Timer: Setter for Minimum Session-Expires, - returns 0 on invalid value */ - int setMinimumTimer(const string& minse); - - bool getEnableSessionTimer() { return EnableSessionTimer; } - unsigned int getSessionExpires() { return SessionExpires; } - unsigned int getMinimumTimer() { return MinimumTimer; } - - int readFromConfig(AmConfigReader& cfg); -}; - #endif // Local Variables: diff --git a/core/AmConfigReader.cpp b/core/AmConfigReader.cpp index 8b3c335d..633abfe2 100644 --- a/core/AmConfigReader.cpp +++ b/core/AmConfigReader.cpp @@ -76,7 +76,7 @@ int AmConfigReader::loadFile(const string& path) if (fname.length() && fname[0] != '/') fname = AmConfig::ModConfigPath + fname; if(loadFile(fname)) - return -1; + goto error; continue; } @@ -139,6 +139,7 @@ int AmConfigReader::loadFile(const string& path) syntax_error: ERROR("syntax error line %i in %s\n",lc,path.c_str()); + error: fclose(fp); return -1; } diff --git a/core/AmSessionEventHandler.cpp b/core/AmSessionEventHandler.cpp index 80aea772..d7b49f7c 100644 --- a/core/AmSessionEventHandler.cpp +++ b/core/AmSessionEventHandler.cpp @@ -28,6 +28,11 @@ #include "AmSessionEventHandler.h" // AmSessionEventHandler methods +int AmSessionEventHandler::configure(AmConfigReader& conf) +{ + return 0; +} + bool AmSessionEventHandler::process(AmEvent*) { return false; diff --git a/core/AmSessionEventHandler.h b/core/AmSessionEventHandler.h index cec7843a..96ee5df2 100644 --- a/core/AmSessionEventHandler.h +++ b/core/AmSessionEventHandler.h @@ -32,6 +32,9 @@ #include "AmSipEvent.h" #include using std::string; + +class AmConfigReader; + /** * \brief Interface for SIP signaling plugins that * change requests or replies using hooks (ex: session timer). @@ -52,6 +55,10 @@ public: : destroy(true) {} virtual ~AmSessionEventHandler() {} + + /** Returns -1 on error, 0 else. */ + virtual int configure(AmConfigReader& conf); + /* * All the methods return true if the event processing * shall be stopped after them. diff --git a/core/plug-in/echo/Echo.cpp b/core/plug-in/echo/Echo.cpp index 7c01f02c..0a88df64 100644 --- a/core/plug-in/echo/Echo.cpp +++ b/core/plug-in/echo/Echo.cpp @@ -29,6 +29,7 @@ #include "AmSession.h" #include "AmConfig.h" #include "AmAudio.h" +#include "AmConfigReader.h" #include "log.h" #include "Echo.h" @@ -47,17 +48,46 @@ EchoFactory::EchoFactory(const string& _app_name) int EchoFactory::onLoad() { - session_timer_f = AmPlugIn::instance()->getFactory4Seh("session_timer"); - if (NULL == session_timer_f) { - ERROR("load session_timer module for echo application.\n"); + bool useSessionTimer = false; + + if(conf.loadFile(AmConfig::ModConfigPath + string(MODULE_NAME)+ ".conf")){ + WARN("Could not open " MODULE_NAME ".conf\n"); + WARN("assuming that default values are fine\n"); } - return (session_timer_f == NULL); + else { + if(conf.hasParameter("enable_session_timer") && + (conf.getParameter("enable_session_timer") == string("yes")) ){ + + useSessionTimer = true; + } + } + + if(useSessionTimer){ + session_timer_f = AmPlugIn::instance()->getFactory4Seh("session_timer"); + DBG("session_timer_f == 0x%.16lX\n",(unsigned long)session_timer_f); + if(session_timer_f == NULL){ + ERROR("Could not load the session_timer module: switch it off\n"); + //return -1; + } + } + + return 0; } AmSession* EchoFactory::onInvite(const AmSipRequest& req) { AmSession* s = new EchoDialog(); - s->addHandler(session_timer_f->getHandler(s)); + + AmSessionEventHandler* h = session_timer_f->getHandler(s); + + if(h->configure(conf)){ + + ERROR("Could not configure the session timer: switch it off.\n"); + delete h; + } + else { + s->addHandler(h); + } return s; } diff --git a/core/plug-in/echo/Echo.h b/core/plug-in/echo/Echo.h index b6ea405a..a8670235 100644 --- a/core/plug-in/echo/Echo.h +++ b/core/plug-in/echo/Echo.h @@ -38,6 +38,7 @@ using std::string; class EchoFactory: public AmSessionFactory { AmSessionEventHandlerFactory* session_timer_f; + AmConfigReader conf; public: EchoFactory(const string& _app_name); @@ -59,6 +60,9 @@ public: void onDtmf(int event, int duration); }; + +#define MODULE_NAME "echo" + #endif // Local Variables: // mode:C++ diff --git a/core/plug-in/session_timer/SessionTimer.cpp b/core/plug-in/session_timer/SessionTimer.cpp index 266c9a1c..f6eb6b3e 100644 --- a/core/plug-in/session_timer/SessionTimer.cpp +++ b/core/plug-in/session_timer/SessionTimer.cpp @@ -99,9 +99,9 @@ bool SessionTimer::onSendRequest(const string& method, if ((method != "INVITE") && (method != "UPDATE")) goto end; - m_hdrs += "Session-Expires: "+ int2str(session_timer_conf.getSessionExpires()) +CRLF - + "Min-SE: " + int2str(session_timer_conf.getMinimumTimer()) + CRLF; - + m_hdrs += "Session-Expires: "+ int2str(session_interval) +CRLF + + "Min-SE: " + int2str(min_se) + CRLF; + end: hdrs += m_hdrs; return false; @@ -114,9 +114,6 @@ bool SessionTimer::onSendReply(const AmSipRequest& req, string& hdrs, int flags) { - //if (!session_timer_conf.getEnableSessionTimer()) - // return ""; - string m_hdrs = SIP_HDR_COLSP(SIP_HDR_SUPPORTED) "timer" CRLF; if ((req.method != "INVITE") && (req.method != "UPDATE")) return false; @@ -136,14 +133,21 @@ bool SessionTimer::onSendReply(const AmSipRequest& req, /* Session Timer: -ssa */ -void SessionTimer::configureSessionTimer(const AmSessionTimerConfig& conf) +int SessionTimer::configure(AmConfigReader& conf) { - session_timer_conf = conf; + if(session_timer_conf.readFromConfig(conf)) + return -1; + + session_interval = session_timer_conf.getSessionExpires(); + min_se = session_timer_conf.getMinimumTimer(); + DBG("Configured session with EnableSessionTimer = %s, SessionExpires = %u, MinimumTimer = %u\n", session_timer_conf.getEnableSessionTimer() ? "yes":"no", session_timer_conf.getSessionExpires(), session_timer_conf.getMinimumTimer() ); + + return 0; } /** @@ -153,15 +157,14 @@ void SessionTimer::configureSessionTimer(const AmSessionTimerConfig& conf) */ bool SessionTimerFactory::checkSessionExpires(const AmSipRequest& req) { - //if (session_timer_conf.getEnableSessionTimer()) { string session_expires = getHeader(req.hdrs, "Session-Expires", "x"); if (session_expires.length()) { unsigned int i_se; if (!str2i(strip_header_params(session_expires), i_se)) { + //if (i_se < session_timer_conf.getMinimumTimer()) { - //TODO: reply_error... - //throw SessionTimerException(session_timer_conf.getMinimumTimer()); + //TODO: reply 422... //} } else throw AmSession::Exception(500,"internal error"); // malformed request? @@ -181,20 +184,17 @@ void SessionTimer::updateTimer(AmSession* s, const AmSipRequest& req) { // determine session interval string sess_expires_hdr = getHeader(req.hdrs, "Session-Expires", "x"); - //session_interval = get_session_interval_from(req); + unsigned int rem_sess_expires=0; if (!sess_expires_hdr.empty()) { if (str2i(strip_header_params(sess_expires_hdr), - session_interval)) { + rem_sess_expires)) { WARN("error while parsing Session-Expires header value '%s'\n", strip_header_params(sess_expires_hdr).c_str()); // exception? - session_interval = session_timer_conf.getSessionExpires(); } - } else { - session_interval = session_timer_conf.getSessionExpires(); } // get Min-SE - unsigned int i_minse = session_timer_conf.getMinimumTimer(); + unsigned int i_minse = min_se; string min_se_hdr = getHeader(req.hdrs, "Min-SE"); if (!min_se_hdr.empty()) { if (str2i(strip_header_params(min_se_hdr), @@ -205,15 +205,15 @@ void SessionTimer::updateTimer(AmSession* s, const AmSipRequest& req) { } // calculate actual se - unsigned int min = session_timer_conf.getMinimumTimer(); - if (i_minse > min) - min = i_minse; - if ((session_timer_conf.getSessionExpires() < min)|| - (session_interval min_se) + min_se = i_minse; + + if (rem_sess_expires < min_se) { + session_interval = min_se; } else { - if (session_timer_conf.getSessionExpires() < session_interval) - session_interval = session_timer_conf.getSessionExpires(); + if (rem_sess_expires < session_interval) + session_interval = rem_sess_expires; } // determine session refresher -- cf rfc4028 Table 2 @@ -254,12 +254,10 @@ void SessionTimer::updateTimer(AmSession* s, const AmSipReply& reply) if (sess_expires_hdr.empty()) sess_expires_hdr = getHeader(reply.hdrs, "x"); // compact form - session_interval = session_timer_conf.getSessionExpires(); session_refresher = refresh_local; session_refresher_role = UAC; if (!sess_expires_hdr.empty()) { - //session_interval = get_session_interval_from(req); unsigned int sess_i_tmp = 0; if (str2i(strip_header_params(sess_expires_hdr), sess_i_tmp)) { @@ -267,8 +265,8 @@ void SessionTimer::updateTimer(AmSession* s, const AmSipReply& reply) strip_header_params(sess_expires_hdr).c_str()); // exception? } else { // this is forbidden by rfc, but to be sure against 'rogue' proxy/uas - if (sess_i_tmp < session_timer_conf.getMinimumTimer()) { - session_interval = session_timer_conf.getMinimumTimer(); + if (sess_i_tmp < min_se) { + session_interval = min_se; } else { session_interval = sess_i_tmp; } @@ -281,7 +279,6 @@ void SessionTimer::updateTimer(AmSession* s, const AmSipReply& reply) removeTimers(s); setTimers(s); - } void SessionTimer::setTimers(AmSession* s) @@ -334,3 +331,68 @@ void SessionTimer::onTimeoutEvent(AmTimeoutEvent* timeout_ev) return; } +AmSessionTimerConfig::AmSessionTimerConfig() + : EnableSessionTimer(DEFAULT_ENABLE_SESSION_TIMER), + SessionExpires(SESSION_EXPIRES), + MinimumTimer(MINIMUM_TIMER) +{ + +} +AmSessionTimerConfig::~AmSessionTimerConfig() +{ +} + +int AmSessionTimerConfig::readFromConfig(AmConfigReader& cfg) +{ + // enable_session_timer + if(cfg.hasParameter("enable_session_timer")){ + if(!setEnableSessionTimer(cfg.getParameter("enable_session_timer"))){ + ERROR("invalid enable_session_timer specified\n"); + return -1; + } + } + + // session_expires + if(cfg.hasParameter("session_expires")){ + if(!setSessionExpires(cfg.getParameter("session_expires"))){ + ERROR("invalid session_expires specified\n"); + return -1; + } + } + + // minimum_timer + if(cfg.hasParameter("minimum_timer")){ + if(!setMinimumTimer(cfg.getParameter("minimum_timer"))){ + ERROR("invalid minimum_timer specified\n"); + return -1; + } + } + return 0; +} + +int AmSessionTimerConfig::setEnableSessionTimer(const string& enable) { + if ( strcasecmp(enable.c_str(), "yes") == 0 ) { + EnableSessionTimer = 1; + } else if ( strcasecmp(enable.c_str(), "no") == 0 ) { + EnableSessionTimer = 0; + } else { + return 0; + } + return 1; +} + +int AmSessionTimerConfig::setSessionExpires(const string& se) { + if(sscanf(se.c_str(),"%u",&SessionExpires) != 1) { + return 0; + } + DBG("setSessionExpires(%i)\n",SessionExpires); + return 1; +} + +int AmSessionTimerConfig::setMinimumTimer(const string& minse) { + if(sscanf(minse.c_str(),"%u",&MinimumTimer) != 1) { + return 0; + } + DBG("setMinimumTimer(%i)\n",MinimumTimer); + return 1; +} diff --git a/core/plug-in/session_timer/SessionTimer.h b/core/plug-in/session_timer/SessionTimer.h index 5d41aba8..7fde1a34 100644 --- a/core/plug-in/session_timer/SessionTimer.h +++ b/core/plug-in/session_timer/SessionTimer.h @@ -40,6 +40,12 @@ class AmTimeoutEvent; #define ID_SESSION_INTERVAL_TIMER -1 #define ID_SESSION_REFRESH_TIMER -2 +/* Session Timer defaul configuration: */ +#define DEFAULT_ENABLE_SESSION_TIMER 1 +#define SESSION_EXPIRES 120 // seconds +#define MINIMUM_TIMER 90 //seconds + + /** \brief Factory of the session timer event handler */ class SessionTimerFactory: public AmSessionEventHandlerFactory { @@ -55,9 +61,43 @@ class SessionTimerFactory: public AmSessionEventHandlerFactory AmSessionEventHandler* getHandler(AmSession* s); }; +/** \brief config for the session timer */ +class AmSessionTimerConfig +{ + + /** Session Timer: enable? */ + int EnableSessionTimer; + /** Session Timer: Desired Session-Expires */ + unsigned int SessionExpires; + /** Session Timer: Minimum Session-Expires */ + unsigned int MinimumTimer; + +public: + AmSessionTimerConfig(); + ~AmSessionTimerConfig(); + + + /** Session Timer: Enable Session Timer? + returns 0 on invalid value */ + int setEnableSessionTimer(const string& enable); + /** Session Timer: Setter for Desired Session-Expires, + returns 0 on invalid value */ + int setSessionExpires(const string& se); + /** Session Timer: Setter for Minimum Session-Expires, + returns 0 on invalid value */ + int setMinimumTimer(const string& minse); + + bool getEnableSessionTimer() { return EnableSessionTimer; } + unsigned int getSessionExpires() { return SessionExpires; } + unsigned int getMinimumTimer() { return MinimumTimer; } + + int readFromConfig(AmConfigReader& cfg); +}; + /** \brief SessionEventHandler for implementing session timer logic for a session */ class SessionTimer: public AmSessionEventHandler { + AmSessionTimerConfig session_timer_conf; AmSession* s; enum SessionRefresher { @@ -69,10 +109,8 @@ class SessionTimer: public AmSessionEventHandler UAS }; - void configureSessionTimer(const AmSessionTimerConfig& conf); - AmSessionTimerConfig session_timer_conf; - bool remote_timer_aware; + unsigned int min_se; unsigned int session_interval; SessionRefresher session_refresher; SessionRefresherRole session_refresher_role; @@ -97,6 +135,7 @@ class SessionTimer: public AmSessionEventHandler virtual ~SessionTimer(){} /* @see AmSessionEventHandler */ + virtual int configure(AmConfigReader& conf); virtual bool process(AmEvent*); virtual bool onSipEvent(AmSipEvent*); virtual bool onSipRequest(const AmSipRequest&); diff --git a/core/sems.h b/core/sems.h index 0b2522b8..ba3856f3 100644 --- a/core/sems.h +++ b/core/sems.h @@ -54,11 +54,6 @@ // session considered dead after 5 minutes no RTP #define DEAD_RTP_TIME 5*60 -/* Session Timer defaul configuration: */ -#define DEFAULT_ENABLE_SESSION_TIMER 1 -#define SESSION_EXPIRES 60 // seconds -#define MINIMUM_TIMER 5 //seconds - #define NUM_MEDIA_PROCESSORS 1 #define MAX_NET_DEVICES 32