[prev in list] [next in list] [prev in thread] [next in thread]
List: semsdev
Subject: [Semsdev] r8 - in trunk: apps/ivr core core/plug-in/echo
From: rco () mail ! berlios ! de (rco () mail ! berlios ! de)
Date: 2006-03-20 13:50:03
Message-ID: 200603201249.k2KCnlEF022920 () sheep ! berlios ! de
[Download RAW message or body]
Author: rco
Date: 2006-03-20 13:49:35 +0100 (Mon, 20 Mar 2006)
New Revision: 8
Added:
trunk/core/AmArg.h
trunk/core/plug-in/session_timer/UserTimer.cpp
trunk/core/plug-in/session_timer/UserTimer.h
Removed:
trunk/core/AmSessionTimer.cpp
trunk/core/AmSessionTimer.h
Modified:
trunk/apps/ivr/Ivr.cpp
trunk/apps/ivr/Ivr.h
trunk/apps/ivr/IvrDialogBase.cpp
trunk/apps/ivr/IvrSipDialog.cpp
trunk/apps/ivr/IvrSipRequest.cpp
trunk/core/AmApi.cpp
trunk/core/AmApi.h
trunk/core/AmEvent.h
trunk/core/AmPlugIn.cpp
trunk/core/AmPlugIn.h
trunk/core/AmSession.cpp
trunk/core/AmSession.h
trunk/core/AmSessionContainer.cpp
trunk/core/plug-in/echo/Echo.cpp
trunk/core/plug-in/session_timer/SessionTimer.cpp
trunk/core/plug-in/session_timer/SessionTimer.h
trunk/core/sems.cpp
Log:
moved the user timer (used to be known as AmSessionTimer) to the session_timer plugin.
added a multi-purpose plugin type. see also AmApi.h for details.
Modified: trunk/apps/ivr/Ivr.cpp
===================================================================
--- trunk/apps/ivr/Ivr.cpp 2006-03-17 14:48:12 UTC (rev 7)
+++ trunk/apps/ivr/Ivr.cpp 2006-03-20 12:49:35 UTC (rev 8)
@@ -30,7 +30,7 @@
#include "AmApi.h"
#include "AmUtils.h"
#include "AmSessionScheduler.h"
-#include "AmSessionTimer.h"
+//#include "AmSessionTimer.h"
#include "AmPlugIn.h"
#include <unistd.h>
@@ -118,7 +118,8 @@
}
IvrFactory::IvrFactory(const string& _app_name)
- : AmSessionFactory(_app_name)
+ : AmSessionFactory(_app_name),
+ user_timer_fact(NULL)
{
}
@@ -205,13 +206,19 @@
if(mod_it == mod_reg.end()){
ERROR("Unknown script name\n");
throw AmSession::Exception(500,"Unknown Application");
- return NULL;
}
IvrScriptDesc& mod_desc = mod_it->second;
- IvrDialog* dlg = new IvrDialog();
+ AmDynInvoke* user_timer = user_timer_fact->getInstance();
+ if(!user_timer){
+ ERROR("could not get a user timer reference\n");
+ throw AmSession::Exception(500,"could not get a user timer reference");
+ }
+
+ IvrDialog* dlg = new IvrDialog(user_timer);
+
PyObject* c_dlg = PyCObject_FromVoidPtr(dlg,NULL);
PyObject* dlg_inst = PyObject_CallMethod(mod_desc.dlg_class,"__new__","OO",
mod_desc.dlg_class,c_dlg);
@@ -318,6 +325,14 @@
*/
int IvrFactory::onLoad()
{
+ user_timer_fact = AmPlugIn::instance()->getFactory4Di("user_timer");
+ if(!user_timer_fact){
+
+ ERROR("could not load user_timer from session_timer plug-in\n");
+ return -1;
+ }
+
+
AmConfigReader cfg;
if(cfg.loadFile(add2path(AmConfig::ModConfigPath,1,MOD_NAME ".conf")))
@@ -403,10 +418,11 @@
return newDlg(req.user);
}
-IvrDialog::IvrDialog()
+IvrDialog::IvrDialog(AmDynInvoke* user_timer)
: py_mod(NULL),
py_dlg(NULL),
- playlist(this)
+ playlist(this),
+ user_timer(user_timer)
{
sip_relay_only = false;
}
@@ -501,12 +517,13 @@
event->processed = true;
}
- AmTimeoutEvent* timeout_event = dynamic_cast<AmTimeoutEvent*>(event);
- if(timeout_event && timeout_event->event_id > 0) {
+ AmPluginEvent* plugin_event = dynamic_cast<AmPluginEvent*>(event);
+ if(plugin_event && plugin_event->name == "timer_timeout") {
PYLOCK;
- callPyEventHandler("onTimer", timeout_event->event_id);
+ callPyEventHandler("onTimer", plugin_event->data.get(0).asInt());
event->processed = true;
}
+
if (!event->processed)
AmB2BCallerSession::process(event);
Modified: trunk/apps/ivr/Ivr.h
===================================================================
--- trunk/apps/ivr/Ivr.h 2006-03-17 14:48:12 UTC (rev 7)
+++ trunk/apps/ivr/Ivr.h 2006-03-20 12:49:35 UTC (rev 8)
@@ -44,27 +44,21 @@
{
PyObject* mod;
PyObject* dlg_class;
- // PyObject* config;
IvrScriptDesc()
: mod(0),
- dlg_class(0)// ,
-// config(0)
+ dlg_class(0)
{}
IvrScriptDesc(const IvrScriptDesc& d)
: mod(d.mod),
- dlg_class(d.dlg_class)// ,
-// config(d.config)
+ dlg_class(d.dlg_class)
{}
IvrScriptDesc(PyObject* mod,
- PyObject* dlg_class// ,
-// PyObject* config
- )
+ PyObject* dlg_class)
: mod(mod),
- dlg_class(dlg_class)// ,
-// config(config)
+ dlg_class(dlg_class)
{}
};
@@ -77,6 +71,8 @@
map<string,IvrScriptDesc> mod_reg;
+ AmDynInvokeFactory* user_timer_fact;
+
void init_python_interpreter();
void import_ivr_builtins();
@@ -112,9 +108,10 @@
void process(AmEvent* event);
public:
+ AmDynInvoke* user_timer;
AmPlaylist playlist;
- IvrDialog();
+ IvrDialog(AmDynInvoke* user_timer);
~IvrDialog();
// must be called before everything else.
Modified: trunk/apps/ivr/IvrDialogBase.cpp
===================================================================
--- trunk/apps/ivr/IvrDialogBase.cpp 2006-03-17 14:48:12 UTC (rev 7)
+++ trunk/apps/ivr/IvrDialogBase.cpp 2006-03-20 12:49:35 UTC (rev 8)
@@ -4,7 +4,7 @@
#include "IvrSipDialog.h"
-#include "AmSessionTimer.h"
+//#include "AmSessionTimer.h"
// Data definition
typedef struct {
@@ -290,8 +290,13 @@
return NULL;
}
- AmSessionTimer::instance()->
- setTimer(id, interval, self->p_dlg->getLocalTag());
+ AmArgArray di_args,ret;
+ di_args.push(id);
+ di_args.push(interval);
+ di_args.push(self->p_dlg->getLocalTag().c_str());
+
+ self->p_dlg->user_timer->
+ invoke("setTimer", di_args, ret);
Py_INCREF(Py_None);
return Py_None;
@@ -310,8 +315,12 @@
return NULL;
}
- AmSessionTimer::instance()->
- removeTimer(id, self->p_dlg->getLocalTag());
+ AmArgArray di_args,ret;
+ di_args.push(id);
+ di_args.push(self->p_dlg->getLocalTag().c_str());
+
+ self->p_dlg->user_timer->
+ invoke("removeTimer",di_args,ret);
Py_INCREF(Py_None);
return Py_None;
@@ -322,8 +331,11 @@
{
assert(self->p_dlg);
- AmSessionTimer::instance()->
- removeUserTimers(self->p_dlg->getLocalTag());
+ AmArgArray di_args,ret;
+ di_args.push(self->p_dlg->getLocalTag().c_str());
+
+ self->p_dlg->user_timer->
+ invoke("removeUserTimers",di_args,ret);
Py_INCREF(Py_None);
return Py_None;
Modified: trunk/apps/ivr/IvrSipDialog.cpp
===================================================================
--- trunk/apps/ivr/IvrSipDialog.cpp 2006-03-17 14:48:12 UTC (rev 7)
+++ trunk/apps/ivr/IvrSipDialog.cpp 2006-03-20 12:49:35 UTC (rev 8)
@@ -1,6 +1,7 @@
#include "IvrSipDialog.h"
-#include "AmSessionTimer.h"
+//#include "AmSessionTimer.h"
#include "AmSipDialog.h"
+#include "log.h"
// Data definition
typedef struct {
Modified: trunk/apps/ivr/IvrSipRequest.cpp
===================================================================
--- trunk/apps/ivr/IvrSipRequest.cpp 2006-03-17 14:48:12 UTC (rev 7)
+++ trunk/apps/ivr/IvrSipRequest.cpp 2006-03-20 12:49:35 UTC (rev 8)
@@ -1,5 +1,5 @@
#include "IvrSipRequest.h"
-#include "AmSessionTimer.h"
+//#include "AmSessionTimer.h"
#include "AmSipRequest.h"
#if 0
Modified: trunk/core/AmApi.cpp
===================================================================
--- trunk/core/AmApi.cpp 2006-03-17 14:48:12 UTC (rev 7)
+++ trunk/core/AmApi.cpp 2006-03-20 12:49:35 UTC (rev 8)
@@ -29,6 +29,19 @@
#include "log.h"
#include "AmSession.h"
+AmDynInvoke::AmDynInvoke() {}
+AmDynInvoke::~AmDynInvoke() {}
+
+void AmDynInvoke::invoke(const string& method, const AmArgArray& args, AmArgArray& ret)
+{
+ throw NotImplemented(method);
+}
+
+AmDynInvokeFactory::AmDynInvokeFactory(const string& name)
+ : AmPluginFactory(name)
+{
+}
+
AmSessionFactory::AmSessionFactory(const string& name)
: AmPluginFactory(name), mod_conf(AmConfig::defaultSessionTimerConfig)
{
Modified: trunk/core/AmApi.h
===================================================================
--- trunk/core/AmApi.h 2006-03-17 14:48:12 UTC (rev 7)
+++ trunk/core/AmApi.h 2006-03-20 12:49:35 UTC (rev 8)
@@ -27,19 +27,36 @@
#ifndef _AmApi_h_
#define _AmApi_h_
-//#include "AmRequest.h"
#include "AmThread.h"
#include "AmSipRequest.h"
#include "AmConfig.h"
+#include "AmArg.h"
#include <string>
#include <map>
using std::map;
using std::string;
-class AmSession;
-class AmSessionEventHandler;
+/**
+ * Multi-purpose plugin class
+ */
+class AmDynInvoke
+{
+public:
+ struct NotImplemented {
+ string what;
+ NotImplemented(const string& w)
+ : what(w) {}
+ };
+ AmDynInvoke();
+ virtual ~AmDynInvoke();
+ virtual void invoke(const string& method, const AmArgArray& args, AmArgArray& ret);
+};
+
+/**
+ * Base class for plugin factories
+ */
class AmPluginFactory
{
string plugin_name;
@@ -61,18 +78,45 @@
virtual int onLoad()=0;
};
+/**
+ * Factory for multi-purpose plugin classes
+ */
+class AmDynInvokeFactory: public AmPluginFactory
+{
+public:
+ AmDynInvokeFactory(const string& name);
+ virtual AmDynInvoke* getInstance()=0;
+};
+
+class AmSession;
+class AmSessionEventHandler;
+
+class AmSessionEventHandlerFactory: public AmPluginFactory
+{
+public:
+ AmSessionEventHandlerFactory(const string& name);
+
+ virtual AmSessionEventHandler* getHandler(AmSession*)=0;
+
+ /**
+ * @return true if session creation should be stopped
+ */
+ virtual bool onInvite(const AmSipRequest& req)=0;
+};
+
+
class AmSessionFactory: public AmPluginFactory
{
AmSessionTimerConfig mod_conf;
protected:
- /**
- * This reads the module configuration from
- * cfg into the modules mod_conf.
- */
- int configureModule(AmConfigReader& cfg);
+ /**
+ * This reads the module configuration from
+ * cfg into the modules mod_conf.
+ */
+ int configureModule(AmConfigReader& cfg);
public:
/**
@@ -93,19 +137,7 @@
virtual AmSession* onInvite(const AmSipRequest& req)=0;
};
-class AmSessionEventHandlerFactory: public AmPluginFactory
-{
-public:
- AmSessionEventHandlerFactory(const string& name);
- virtual AmSessionEventHandler* getHandler(AmSession*)=0;
-
- /**
- * @return true if session creation should be stopped
- */
- virtual bool onInvite(const AmSipRequest& req)=0;
-};
-
#define EXPORT_FACTORY(fctname,class_name,...) \
extern "C" void* fctname()\
{\
@@ -129,6 +161,12 @@
#define EXPORT_SESSION_EVENT_HANDLER_FACTORY(class_name,app_name) \
EXPORT_FACTORY(FACTORY_SESSION_EVENT_HANDLER_EXPORT,class_name,app_name)
+#define FACTORY_PLUGIN_CLASS_EXPORT plugin_class_create
+#define FACTORY_PLUGIN_CLASS_EXPORT_STR XSTR(FACTORY_PLUGIN_CLASS_EXPORT)
+
+#define EXPORT_PLUGIN_CLASS_FACTORY(class_name,app_name) \
+ EXPORT_FACTORY(FACTORY_PLUGIN_CLASS_EXPORT,class_name,app_name)
+
#endif
// Local Variables:
// mode:C++
Added: trunk/core/AmArg.h
===================================================================
--- trunk/core/AmArg.h 2006-03-17 14:48:12 UTC (rev 7)
+++ trunk/core/AmArg.h 2006-03-20 12:49:35 UTC (rev 8)
@@ -0,0 +1,88 @@
+#ifndef _AmArg_h_
+#define _AmArg_h_
+
+#include <assert.h>
+
+#include <vector>
+using std::vector;
+
+class AmArg
+{
+public:
+ // type enum
+ enum {
+ Undef=0,
+
+ Int,
+ Double,
+ CStr
+ };
+
+private:
+ // type
+ short type;
+
+ // value
+ union {
+
+ int v_int;
+ double v_double;
+ const char* v_cstr;
+ };
+
+public:
+ AmArg(const AmArg& v)
+ : type(v.type){
+
+ switch(type){
+ case Int: v_int = v.v_int; break;
+ case Double: v_double = v.v_double; break;
+ case CStr: v_cstr = v.v_cstr; break;
+ default: assert(0);
+ }
+ }
+
+ AmArg(const int& v)
+ : type(Int),
+ v_int(v)
+ {}
+
+ AmArg(const double& v)
+ : type(Double),
+ v_double(v)
+ {}
+
+ AmArg(const char* v)
+ : type(CStr),
+ v_cstr(v)
+ {}
+
+ short getType() const { return type; }
+
+ int asInt() const { return v_int; }
+ double asDouble() const { return v_double; }
+ const char* asCStr() const { return v_cstr; }
+};
+
+class AmArgArray
+{
+ vector<AmArg> v;
+
+public:
+ AmArgArray() : v() {}
+ AmArgArray(const AmArgArray& a) : v(a.v) {}
+
+ void push(const AmArg& a){
+ v.push_back(a);
+ }
+
+ const AmArg& get(size_t idx) const {
+
+ assert(idx < v.size());
+ return v[idx];
+ }
+
+ size_t size() { return v.size(); }
+};
+
+#endif
Modified: trunk/core/AmEvent.h
===================================================================
--- trunk/core/AmEvent.h 2006-03-17 14:48:12 UTC (rev 7)
+++ trunk/core/AmEvent.h 2006-03-20 12:49:35 UTC (rev 8)
@@ -1,6 +1,13 @@
#ifndef AmEvent_h
#define AmEvent_h
+#include "AmArg.h"
+
+#include <string>
+using std::string;
+
+#define E_PLUGIN 100
+
struct AmEvent
{
int event_id;
@@ -10,6 +17,20 @@
virtual ~AmEvent();
};
+struct AmPluginEvent: public AmEvent
+{
+ string name;
+ AmArgArray data;
+
+ AmPluginEvent(const string& n)
+ : AmEvent(E_PLUGIN), name(n), data() {}
+
+ AmPluginEvent(const string& n, const AmArgArray& d)
+ : AmEvent(E_PLUGIN), name(n), data(d) {}
+};
+
+
+
class AmEventHandler
{
public:
Modified: trunk/core/AmPlugIn.cpp
===================================================================
--- trunk/core/AmPlugIn.cpp 2006-03-17 14:48:12 UTC (rev 7)
+++ trunk/core/AmPlugIn.cpp 2006-03-20 12:49:35 UTC (rev 8)
@@ -123,6 +123,13 @@
if(err)
break;
}
+
+ for(map<string,AmDynInvokeFactory*>::iterator it = name2di.begin();
+ it != name2di.end(); it++){
+ err = it->second->onLoad();
+ if(err)
+ break;
+ }
map<string,AmSessionFactory*> apps(name2app);
for(map<string,AmSessionFactory*>::iterator it = apps.begin();
@@ -149,6 +156,7 @@
FactoryCreate fc = NULL;
amci_exports_t* exports = (amci_exports_t*)dlsym(h_dl,"amci_exports");
+ bool has_sym=false;
if(exports){
if(loadAudioPlugIn(exports))
goto error;
@@ -158,12 +166,20 @@
if((fc = (FactoryCreate)dlsym(h_dl,FACTORY_SESSION_EXPORT_STR)) != NULL){
if(loadAppPlugIn((AmPluginFactory*)fc()))
goto error;
+ has_sym=true;
}
- else if((fc = (FactoryCreate)dlsym(h_dl,FACTORY_SESSION_EVENT_HANDLER_EXPORT_STR)) != NULL){
+ if((fc = (FactoryCreate)dlsym(h_dl,FACTORY_SESSION_EVENT_HANDLER_EXPORT_STR)) != NULL){
if(loadSehPlugIn((AmPluginFactory*)fc()))
goto error;
+ has_sym=true;
}
- else {
+ if((fc = (FactoryCreate)dlsym(h_dl,FACTORY_PLUGIN_CLASS_EXPORT_STR)) != NULL){
+ if(loadDiPlugIn((AmPluginFactory*)fc()))
+ goto error;
+ has_sym=true;
+ }
+
+ if(!has_sym){
ERROR("Plugin type could not be detected (%s)(%s)\n",file.c_str(),dlerror());
goto error;
}
@@ -251,6 +267,14 @@
return 0;
}
+AmDynInvokeFactory* AmPlugIn::getFactory4Di(const string& name)
+{
+ map<string,AmDynInvokeFactory*>::iterator it = name2di.find(name);
+ if(it != name2di.end())
+ return it->second;
+ return 0;
+}
+
int AmPlugIn::loadAudioPlugIn(amci_exports_t* exports)
{
if(!exports){
@@ -299,13 +323,8 @@
goto error;
}
- //if(!sf->onLoad()){
- name2app.insert(std::make_pair(sf->getName(),sf));
- DBG("application '%s' loaded.\n",sf->getName().c_str());
-// }
-// else {
-// goto error;
-// }
+ name2app.insert(std::make_pair(sf->getName(),sf));
+ DBG("application '%s' loaded.\n",sf->getName().c_str());
return 0;
@@ -326,13 +345,8 @@
goto error;
}
-// if(!sf->onLoad()){
- name2seh.insert(std::make_pair(sf->getName(),sf));
- DBG("session component '%s' loaded.\n",sf->getName().c_str());
-// }
-// else {
-// goto error;
-// }
+ name2seh.insert(std::make_pair(sf->getName(),sf));
+ DBG("session component '%s' loaded.\n",sf->getName().c_str());
return 0;
@@ -340,7 +354,29 @@
return -1;
}
+int AmPlugIn::loadDiPlugIn(AmPluginFactory* f)
+{
+ AmDynInvokeFactory* sf = dynamic_cast<AmDynInvokeFactory*>(f);
+ if(!sf){
+ ERROR("invalid component plug-in!\n");
+ goto error;
+ }
+ if(name2di.find(sf->getName()) != name2di.end()){
+ ERROR("component '%s' already loaded !\n",sf->getName().c_str());
+ goto error;
+ }
+
+ name2di.insert(std::make_pair(sf->getName(),sf));
+ DBG("component '%s' loaded.\n",sf->getName().c_str());
+
+ return 0;
+
+ error:
+ return -1;
+}
+
+
int AmPlugIn::addCodec(amci_codec_t* c)
{
if(codecs.find(c->id) != codecs.end()){
Modified: trunk/core/AmPlugIn.h
===================================================================
--- trunk/core/AmPlugIn.h 2006-03-17 14:48:12 UTC (rev 7)
+++ trunk/core/AmPlugIn.h 2006-03-20 12:49:35 UTC (rev 8)
@@ -38,6 +38,7 @@
class AmPluginFactory;
class AmSessionFactory;
class AmSessionEventHandlerFactory;
+class AmDynInvokeFactory;
struct amci_exports_t;
struct amci_codec_t;
@@ -67,6 +68,7 @@
map<string,AmSessionFactory*> name2app;
map<string,AmSessionEventHandlerFactory*> name2seh;
+ map<string,AmDynInvokeFactory*> name2di;
int dynamic_pl; // range: 96->127, see RFC 1890
@@ -78,6 +80,7 @@
int loadAudioPlugIn(amci_exports_t* exports);
int loadAppPlugIn(AmPluginFactory* cb);
int loadSehPlugIn(AmPluginFactory* cb);
+ int loadDiPlugIn(AmPluginFactory* cb);
int addCodec(amci_codec_t* c);
int addPayload(amci_payload_t* p);
@@ -136,6 +139,11 @@
*/
AmSessionEventHandlerFactory* getFactory4Seh(const string& name);
+ /**
+ * Dynamic invokation component
+ */
+ AmDynInvokeFactory* getFactory4Di(const string& name);
+
/** @return true if this record has been inserted. */
bool registerFactory4App(const string& app_name, AmSessionFactory* f);
};
Modified: trunk/core/AmSession.cpp
===================================================================
--- trunk/core/AmSession.cpp 2006-03-17 14:48:12 UTC (rev 7)
+++ trunk/core/AmSession.cpp 2006-03-20 12:49:35 UTC (rev 8)
@@ -38,7 +38,7 @@
#include "AmSessionScheduler.h"
#include "AmDtmfDetector.h"
/* Session Timer: -ssa */
-#include "AmSessionTimer.h"
+//#include "AmSessionTimer.h"
#include "log.h"
@@ -315,7 +315,7 @@
}
}
// remove pending timers
- AmSessionTimer::instance()->removeTimers(getLocalTag());
+ //AmSessionTimer::instance()->removeTimers(getLocalTag());
}
catch(const AmSession::Exception& e){ throw e; }
catch(const string& str){
@@ -555,10 +555,10 @@
return -1;
}
-string AmSession::SessionTimerException::getErrorHeaders() const {
- return "Min-SE:" + int2str(minSE) + "\n"
- + "Supported: timer\n";
-}
+// string AmSession::SessionTimerException::getErrorHeaders() const {
+// return "Min-SE:" + int2str(minSE) + "\n"
+// + "Supported: timer\n";
+// }
void AmSession::onSendRequest(const string& method, const string& content_type,
const string& body, string& hdrs)
Modified: trunk/core/AmSession.h
===================================================================
--- trunk/core/AmSession.h 2006-03-17 14:48:12 UTC (rev 7)
+++ trunk/core/AmSession.h 2006-03-20 12:49:35 UTC (rev 8)
@@ -53,14 +53,7 @@
//class AmDialogState;
class AmDtmfEvent;
-/* Session Timer: -ssa */
-class AmTimeoutEvent;
-// these are the timer IDs for session timer
-// Caution: do not use these for other purposes
-#define ID_SESSION_INTERVAL_TIMER -1
-#define ID_SESSION_REFRESH_TIMER -2
-
/**
* Signaling plugins must inherite from this class.
*/
@@ -153,15 +146,15 @@
Exception(int c, string r) : code(c), reason(r) {}
};
- struct SessionTimerException : Exception {
- unsigned int minSE;
+// struct SessionTimerException : Exception {
+// unsigned int minSE;
- SessionTimerException(unsigned int min_SE)
- : Exception(422, "Session Interval Too Small"),
- minSE(min_SE) { }
+// SessionTimerException(unsigned int min_SE)
+// : Exception(422, "Session Interval Too Small"),
+// minSE(min_SE) { }
- string getErrorHeaders() const;
- };
+// string getErrorHeaders() const;
+// };
/**
* Session constructor.
Modified: trunk/core/AmSessionContainer.cpp
===================================================================
--- trunk/core/AmSessionContainer.cpp 2006-03-17 14:48:12 UTC (rev 7)
+++ trunk/core/AmSessionContainer.cpp 2006-03-20 12:49:35 UTC (rev 8)
@@ -185,10 +185,10 @@
//throw AmSession::Exception(500,"internal error");
}
}
- catch(const AmSession::SessionTimerException& e){
- ERROR("%i %s\n",e.code,e.reason.c_str());
- AmSipDialog::reply_error(req,e.code,e.reason,e.getErrorHeaders());
- }
+// catch(const AmSession::SessionTimerException& e){
+// ERROR("%i %s\n",e.code,e.reason.c_str());
+// AmSipDialog::reply_error(req,e.code,e.reason,e.getErrorHeaders());
+// }
catch(const AmSession::Exception& e){
ERROR("%i %s\n",e.code,e.reason.c_str());
AmSipDialog::reply_error(req,e.code,e.reason);
Deleted: trunk/core/AmSessionTimer.cpp
===================================================================
--- trunk/core/AmSessionTimer.cpp 2006-03-17 14:48:12 UTC (rev 7)
+++ trunk/core/AmSessionTimer.cpp 2006-03-20 12:49:35 UTC (rev 8)
@@ -1,145 +0,0 @@
-
-#include "AmSessionTimer.h"
-
-#include <sys/time.h>
-
-#define SESSION_TIMER_GRANULARITY 100 // check every 100 millisec
-
-
-AmSessionTimer::AmSessionTimer()
-{
-}
-
-AmSessionTimer::~AmSessionTimer()
-{
-}
-
-AmSessionTimer* AmSessionTimer::_instance=0;
-
-AmSessionTimer* AmSessionTimer::instance()
-{
- if(!_instance)
- _instance = new AmSessionTimer();
- return _instance;
-}
-
-#ifdef SESSION_TIMER_THREAD
-void AmSessionTimer::run() {
- while(1){
- usleep(SESSION_TIMER_GRANULARITY * 1000);
- checkTimers();
- }
-}
-
-void AmSessionTimer::on_stop() {
-}
-#endif // SESSION_TIMER_THREAD
-
-bool operator < (const AmTimer& l, const AmTimer& r)
-{
- return timercmp(&l.time,&r.time,<);
-}
-
-bool operator == (const AmTimer& l, const AmTimer& r)
-{
- return l.id == r.id;
-}
-
-void AmSessionTimer::checkTimers() {
- timers_mut.lock();
- if(timers.empty()){
- timers_mut.unlock();
- return;
- }
-
- struct timeval cur_time;
- gettimeofday(&cur_time,NULL);
-
- set<AmTimer>::iterator it = timers.begin();
-
- while( timercmp(&it->time,&cur_time,<)
- || timercmp(&it->time,&cur_time,==) ){
- int id = it->id;
- string session_id = it->session_id;
- // erase
- timers.erase(it);
- // 'fire' timer
- if (!AmSessionContainer::instance()->postEvent(session_id,
- new AmTimeoutEvent(id))) {
- DBG("Timeout Event could not be posted, session does not exist any more.\n");
- }
-
-
- if(timers.empty()) break;
- it = timers.begin();
- }
- timers_mut.unlock();
-}
-
-void AmSessionTimer::setTimer(int id, int seconds, const string& session_id) {
- struct timeval tval;
- gettimeofday(&tval,NULL);
-
- tval.tv_sec += seconds;
- setTimer(id, &tval, session_id);
-}
-
-void AmSessionTimer::setTimer(int id, struct timeval* t,
- const string& session_id)
-{
- timers_mut.lock();
-
- // erase old timer if exists
- unsafe_removeTimer(id, session_id);
-
- // add new
- timers.insert(AmTimer(id, session_id, t));
-
- timers_mut.unlock();
-}
-
-
-void AmSessionTimer::removeTimer(int id, const string& session_id) {
- timers_mut.lock();
- unsafe_removeTimer(id, session_id);
- timers_mut.unlock();
-}
-
-void AmSessionTimer::unsafe_removeTimer(int id, const string& session_id)
-{
- // erase old timer if exists
- set<AmTimer>::iterator it = timers.begin();
- while (it != timers.end()) {
- if ((it->id == id)&&(it->session_id == session_id)) {
- timers.erase(it);
- break;
- }
- it++;
- }
-}
-
-void AmSessionTimer::removeTimers(const string& session_id) {
- // DBG("removing timers for <%s>\n", session_id.c_str());
- timers_mut.lock();
- for (set<AmTimer>::iterator it = timers.begin();
- it != timers.end(); it++) {
- if (it->session_id == session_id) {
- timers.erase(it);
- // DBG(" o timer removed.\n");
- }
- }
- timers_mut.unlock();
-}
-
-void AmSessionTimer::removeUserTimers(const string& session_id) {
- // DBG("removing User timers for <%s>\n", session_id.c_str());
- timers_mut.lock();
- for (set<AmTimer>::iterator it = timers.begin();
- it != timers.end(); it++) {
- if ((it->id > 0)&&(it->session_id == session_id)) {
- timers.erase(it);
- // DBG(" o timer removed.\n");
- }
- }
- timers_mut.unlock();
-}
Deleted: trunk/core/AmSessionTimer.h
===================================================================
--- trunk/core/AmSessionTimer.h 2006-03-17 14:48:12 UTC (rev 7)
+++ trunk/core/AmSessionTimer.h 2006-03-20 12:49:35 UTC (rev 8)
@@ -1,89 +0,0 @@
-
-/*
- * Timer class with seconds granularity
- */
-#ifndef AM_SESSION_TIMER_H
-#define AM_SESSION_TIMER_H
-
-// if the CallTimer should run as separate thread,
-// define this one, otherwise call
-// checkTimers periodically
-#define SESSION_TIMER_THREAD
-
-#define TIMEOUT_EVENT_ID 99
-
-#ifdef SESSION_TIMER_THREAD
-#include "AmThread.h"
-#endif
-#include "AmSessionContainer.h"
-
-#include <set>
-
-class AmTimeoutEvent : public AmEvent {
- public:
- AmTimeoutEvent(int timer_id)
- : AmEvent(timer_id) { }
-};
-
-struct AmTimer
-{
- int id;
- string session_id;
-
- struct timeval time;
-
- AmTimer(int id, const string& session_id, struct timeval* tval)
- : id(id), session_id(session_id), time(*tval) {}
-};
-
-
-
-bool operator < (const AmTimer& l, const AmTimer& r);
-bool operator == (const AmTimer& l, const AmTimer& r);
-
-/**
- * session timer class.
- * Implements a timer with session granularity.
- * On timeout an AmTimeoutEvent with the ID is posted.
- */
-class AmSessionTimer
-#ifdef SESSION_TIMER_THREAD
-: public AmThread
-#endif
-{
- static AmSessionTimer* _instance;
-
- std::set<AmTimer> timers;
- AmMutex timers_mut;
-
- void unsafe_removeTimer(int id, const string& session_id);
- public:
- AmSessionTimer();
- ~AmSessionTimer();
-
- static AmSessionTimer* instance();
-
- /** set timer with ID id, fire after s seconds event in
- session session_id */
- void setTimer(int id, int seconds, const string& session_id);
- /** set timer with ID id, fire at time t event in session session_id */
- void setTimer(int id, struct timeval* t, const string& session_id);
-
- /** remove timer with ID id */
- void removeTimer(int id, const string& session_id);
- /** remove all timers belonging to the session session_id */
- void removeTimers(const string& session_id);
- /** remove all timers belonging to the session session_id with an ID > 0 */
- void removeUserTimers(const string& session_id);
-
- /** ifndef SESSION_TIMER_THREAD, this routine must be
- * periodically called. */
- void checkTimers();
-
-#ifdef SESSION_TIMER_THREAD
- void run();
- void on_stop();
-#endif
-};
-
-#endif //AM_SESSION_TIMER_H
Modified: trunk/core/plug-in/echo/Echo.cpp
===================================================================
--- trunk/core/plug-in/echo/Echo.cpp 2006-03-17 14:48:12 UTC (rev 7)
+++ trunk/core/plug-in/echo/Echo.cpp 2006-03-20 12:49:35 UTC (rev 8)
@@ -56,8 +56,6 @@
AmSession* EchoFactory::onInvite(const AmSipRequest& req)
{
-// if()
-
AmSession* s = new EchoDialog();
s->addHandler(session_timer_f->getHandler(s));
Modified: trunk/core/plug-in/session_timer/SessionTimer.cpp
===================================================================
--- trunk/core/plug-in/session_timer/SessionTimer.cpp 2006-03-17 14:48:12 UTC (rev 7)
+++ trunk/core/plug-in/session_timer/SessionTimer.cpp 2006-03-20 12:49:35 UTC (rev 8)
@@ -1,6 +1,6 @@
#include "SessionTimer.h"
#include "AmUtils.h"
-#include "AmSessionTimer.h"
+#include "UserTimer.h"
EXPORT_SESSION_EVENT_HANDLER_FACTORY(SessionTimerFactory, MOD_NAME);
@@ -34,7 +34,7 @@
/* Session Timer: -ssa */
AmTimeoutEvent* timeout_ev = dynamic_cast<AmTimeoutEvent*>(ev);
if (timeout_ev) {
- DBG("received timeout Event with ID %d\n", ev->event_id);
+ DBG("received timeout Event with ID %d\n", timeout_ev->data.get(0).asInt());
onTimeoutEvent(timeout_ev);
return true;
}
@@ -264,23 +264,23 @@
DBG("Setting session interval timer: %ds, tag '%s'\n", session_interval,
s->getLocalTag().c_str());
- AmSessionTimer::instance()->
+ UserTimer::instance()->
setTimer(ID_SESSION_INTERVAL_TIMER, session_interval, s->getLocalTag());
// set session refresh action timer, after half the expiration
if (session_refresher == refresh_local) {
- DBG("Setting session refresh timer: %ds, tag '%s'\n", session_interval/2,
- s->getLocalTag().c_str());
- AmSessionTimer::instance()->
- setTimer(ID_SESSION_REFRESH_TIMER, session_interval/2, s->getLocalTag());
+ DBG("Setting session refresh timer: %ds, tag '%s'\n", session_interval/2,
+ s->getLocalTag().c_str());
+ UserTimer::instance()->
+ setTimer(ID_SESSION_REFRESH_TIMER, session_interval/2, s->getLocalTag());
}
}
void SessionTimer::removeTimers(AmSession* s)
{
- AmSessionTimer::instance()->
+ UserTimer::instance()->
removeTimer(ID_SESSION_REFRESH_TIMER, s->getLocalTag());
- AmSessionTimer::instance()->
+ UserTimer::instance()->
removeTimer(ID_SESSION_INTERVAL_TIMER, s->getLocalTag());
}
@@ -288,13 +288,14 @@
{
// if (!session_timer_conf.getEnableSessionTimer())
// return;
-
- if (timeout_ev->event_id == ID_SESSION_REFRESH_TIMER) {
+ int timer_id = timeout_ev->data.get(0).asInt();
+
+ if (timer_id == ID_SESSION_REFRESH_TIMER) {
if (session_refresher == refresh_local)
s->sendReinvite();
else
WARN("need session refresh but remote session is refresher\n");
- } else if (timeout_ev->event_id == ID_SESSION_INTERVAL_TIMER) {
+ } else if (timer_id == ID_SESSION_INTERVAL_TIMER) {
// // let the session know it got timeout
// onTimeout();
Modified: trunk/core/plug-in/session_timer/SessionTimer.h
===================================================================
--- trunk/core/plug-in/session_timer/SessionTimer.h 2006-03-17 14:48:12 UTC (rev 7)
+++ trunk/core/plug-in/session_timer/SessionTimer.h 2006-03-20 12:49:35 UTC (rev 8)
@@ -6,6 +6,14 @@
#define MOD_NAME "session_timer"
+/* Session Timer: -ssa */
+class AmTimeoutEvent;
+// these are the timer IDs for session timer
+// Caution: do not use these for other purposes
+#define ID_SESSION_INTERVAL_TIMER -1
+#define ID_SESSION_REFRESH_TIMER -2
+
+
class SessionTimerFactory: public AmSessionEventHandlerFactory
{
bool checkSessionExpires(const AmSipRequest& req);
Added: trunk/core/plug-in/session_timer/UserTimer.cpp
===================================================================
--- trunk/core/plug-in/session_timer/UserTimer.cpp 2006-03-17 14:48:12 UTC (rev 7)
+++ trunk/core/plug-in/session_timer/UserTimer.cpp 2006-03-20 12:49:35 UTC (rev 8)
@@ -0,0 +1,192 @@
+
+#include "UserTimer.h"
+
+#include <sys/time.h>
+
+#define SESSION_TIMER_GRANULARITY 100 // check every 100 millisec
+
+class UserTimerFactory: public AmDynInvokeFactory
+{
+public:
+ UserTimerFactory(const string& name)
+ : AmDynInvokeFactory(name) {}
+
+ AmDynInvoke* getInstance(){
+ return UserTimer::instance();
+ }
+
+ int onLoad(){
+#ifdef SESSION_TIMER_THREAD
+ UserTimer::instance()->start();
+#endif
+ return 0;
+ }
+};
+
+
+EXPORT_PLUGIN_CLASS_FACTORY(UserTimerFactory,"user_timer");
+
+AmTimeoutEvent::AmTimeoutEvent(int timer_id)
+ : AmPluginEvent(TIMEOUTEVENT_NAME)
+{
+ data.push(AmArg(timer_id));
+}
+
+
+UserTimer::UserTimer()
+{
+}
+
+UserTimer::~UserTimer()
+{
+}
+
+UserTimer* UserTimer::_instance=0;
+
+UserTimer* UserTimer::instance()
+{
+ if(!_instance)
+ _instance = new UserTimer();
+ return _instance;
+}
+
+#ifdef SESSION_TIMER_THREAD
+void UserTimer::run() {
+ while(1){
+ usleep(SESSION_TIMER_GRANULARITY * 1000);
+ checkTimers();
+ }
+}
+
+void UserTimer::on_stop() {
+}
+#endif // SESSION_TIMER_THREAD
+
+bool operator < (const AmTimer& l, const AmTimer& r)
+{
+ return timercmp(&l.time,&r.time,<);
+}
+
+bool operator == (const AmTimer& l, const AmTimer& r)
+{
+ return l.id == r.id;
+}
+
+void UserTimer::checkTimers() {
+ timers_mut.lock();
+ if(timers.empty()){
+ timers_mut.unlock();
+ return;
+ }
+
+ struct timeval cur_time;
+ gettimeofday(&cur_time,NULL);
+
+ set<AmTimer>::iterator it = timers.begin();
+
+ while( timercmp(&it->time,&cur_time,<)
+ || timercmp(&it->time,&cur_time,==) ){
+ int id = it->id;
+ string session_id = it->session_id;
+ // erase
+ timers.erase(it);
+ // 'fire' timer
+ if (!AmSessionContainer::instance()->postEvent(session_id,
+ new AmTimeoutEvent(id))) {
+ DBG("Timeout Event could not be posted, session does not exist any more.\n");
+ }
+ else {
+ DBG("Timeout Event could be posted.\n");
+ }
+
+ if(timers.empty()) break;
+ it = timers.begin();
+ }
+ timers_mut.unlock();
+}
+
+void UserTimer::setTimer(int id, int seconds, const string& session_id) {
+ struct timeval tval;
+ gettimeofday(&tval,NULL);
+
+ tval.tv_sec += seconds;
+ setTimer(id, &tval, session_id);
+}
+
+void UserTimer::setTimer(int id, struct timeval* t,
+ const string& session_id)
+{
+ timers_mut.lock();
+
+ // erase old timer if exists
+ unsafe_removeTimer(id, session_id);
+
+ // add new
+ timers.insert(AmTimer(id, session_id, t));
+
+ timers_mut.unlock();
+}
+
+
+void UserTimer::removeTimer(int id, const string& session_id) {
+ timers_mut.lock();
+ unsafe_removeTimer(id, session_id);
+ timers_mut.unlock();
+}
+
+void UserTimer::unsafe_removeTimer(int id, const string& session_id)
+{
+ // erase old timer if exists
+ set<AmTimer>::iterator it = timers.begin();
+ while (it != timers.end()) {
+ if ((it->id == id)&&(it->session_id == session_id)) {
+ timers.erase(it);
+ break;
+ }
+ it++;
+ }
+}
+
+void UserTimer::removeTimers(const string& session_id) {
+ // DBG("removing timers for <%s>\n", session_id.c_str());
+ timers_mut.lock();
+ for (set<AmTimer>::iterator it = timers.begin();
+ it != timers.end(); it++) {
+ if (it->session_id == session_id) {
+ timers.erase(it);
+ // DBG(" o timer removed.\n");
+ }
+ }
+ timers_mut.unlock();
+}
+
+void UserTimer::removeUserTimers(const string& session_id) {
+ // DBG("removing User timers for <%s>\n", session_id.c_str());
+ timers_mut.lock();
+ for (set<AmTimer>::iterator it = timers.begin();
+ it != timers.end(); it++) {
+ if ((it->id > 0)&&(it->session_id == session_id)) {
+ timers.erase(it);
+ // DBG(" o timer removed.\n");
+ }
+ }
+ timers_mut.unlock();
+}
+
+void UserTimer::invoke(const string& method, const AmArgArray& args, AmArgArray& ret)
+{
+ if(method == "setTimer"){
+ setTimer(args.get(0).asInt(),
+ args.get(1).asInt(),
+ args.get(2).asCStr());
+ }
+ else if(method == "removeTimer"){
+ removeTimer(args.get(0).asInt(),
+ args.get(1).asCStr());
+ }
+ else if(method == "removeUserTimers"){
+ removeUserTimers(args.get(0).asCStr());
+ }
+ else
+ throw AmDynInvoke::NotImplemented(method);
+}
Added: trunk/core/plug-in/session_timer/UserTimer.h
===================================================================
--- trunk/core/plug-in/session_timer/UserTimer.h 2006-03-17 14:48:12 UTC (rev 7)
+++ trunk/core/plug-in/session_timer/UserTimer.h 2006-03-20 12:49:35 UTC (rev 8)
@@ -0,0 +1,102 @@
+/*
+ * Timer class with seconds granularity
+ */
+#ifndef AM_SESSION_TIMER_H
+#define AM_SESSION_TIMER_H
+
+// if the CallTimer should run as separate thread,
+// define this one, otherwise call
+// checkTimers periodically
+#define SESSION_TIMER_THREAD
+
+#define TIMEOUT_EVENT_ID 99
+
+#ifdef SESSION_TIMER_THREAD
+#include "AmThread.h"
+#endif
+#include "AmSessionContainer.h"
+
+#include <set>
+
+/**
+ * Timer Event: Name
+ */
+#define TIMEOUTEVENT_NAME "timer_timeout"
+
+/**
+ * Timer Event: class
+ * data[0]: int timer_id
+ */
+class AmTimeoutEvent : public AmPluginEvent
+{
+ public:
+ AmTimeoutEvent(int timer_id);
+};
+
+/**
+ * Timer struct containing the alarm time.
+ */
+struct AmTimer
+{
+ int id;
+ string session_id;
+
+ struct timeval time;
+
+ AmTimer(int id, const string& session_id, struct timeval* tval)
+ : id(id), session_id(session_id), time(*tval) {}
+};
+
+
+
+bool operator < (const AmTimer& l, const AmTimer& r);
+bool operator == (const AmTimer& l, const AmTimer& r);
+
+/**
+ * session timer class.
+ * Implements a timer with session granularity.
+ * On timeout an AmTimeoutEvent with the ID is posted.
+ */
+class UserTimer: public AmDynInvoke
+#ifdef SESSION_TIMER_THREAD
+,public AmThread
+#endif
+{
+ static UserTimer* _instance;
+
+ std::set<AmTimer> timers;
+ AmMutex timers_mut;
+
+ void unsafe_removeTimer(int id, const string& session_id);
+ public:
+ UserTimer();
+ ~UserTimer();
+
+ static UserTimer* instance();
+
+ /** set timer with ID id, fire after s seconds event in
+ session session_id */
+ void setTimer(int id, int seconds, const string& session_id);
+ /** set timer with ID id, fire at time t event in session session_id */
+ void setTimer(int id, struct timeval* t, const string& session_id);
+
+ /** remove timer with ID id */
+ void removeTimer(int id, const string& session_id);
+ /** remove all timers belonging to the session session_id */
+ void removeTimers(const string& session_id);
+ /** remove all timers belonging to the session session_id with an ID > 0 */
+ void removeUserTimers(const string& session_id);
+
+ /** ifndef SESSION_TIMER_THREAD, this routine must be
+ * periodically called. */
+ void checkTimers();
+
+#ifdef SESSION_TIMER_THREAD
+ void run();
+ void on_stop();
+#endif
+
+ void invoke(const string& method, const AmArgArray& args, AmArgArray& ret);
+};
+
+#endif //AM_SESSION_TIMER_H
Modified: trunk/core/sems.cpp
===================================================================
--- trunk/core/sems.cpp 2006-03-17 14:48:12 UTC (rev 7)
+++ trunk/core/sems.cpp 2006-03-20 12:49:35 UTC (rev 8)
@@ -38,7 +38,7 @@
#include "AmSessionScheduler.h"
#include "AmIcmpWatcher.h"
#include "AmRtpReceiver.h"
-#include "AmSessionTimer.h"
+//#include "AmSessionTimer.h"
#include "log.h"
@@ -412,8 +412,8 @@
DBG("Starting RTP receiver\n");
AmRtpReceiver::instance()->start();
- DBG("Starting Session Timer\n");
- AmSessionTimer::instance()->start();
+ //DBG("Starting Session Timer\n");
+ //AmSessionTimer::instance()->start();
//DBG("Starting ICMP watcher\n");
//AmIcmpWatcher::instance()->start();
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic