Browse code

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.

git-svn-id: http://svn.berlios.de/svnroot/repos/sems/trunk@8 8eb893ce-cfd4-0310-b710-fb5ebe64c474

Raphael Coeffic authored on 20/03/2006 12:49:35
Showing 20 changed files
... ...
@@ -30,7 +30,7 @@
30 30
 #include "AmApi.h"
31 31
 #include "AmUtils.h"
32 32
 #include "AmSessionScheduler.h"
33
-#include "AmSessionTimer.h"
33
+//#include "AmSessionTimer.h"
34 34
 #include "AmPlugIn.h"
35 35
 
36 36
 #include <unistd.h>
... ...
@@ -118,7 +118,8 @@ extern "C" {
118 118
 }
119 119
 
120 120
 IvrFactory::IvrFactory(const string& _app_name)
121
-  : AmSessionFactory(_app_name)
121
+    : AmSessionFactory(_app_name),
122
+      user_timer_fact(NULL)
122 123
 {
123 124
 }
124 125
 
... ...
@@ -205,12 +206,18 @@ IvrDialog* IvrFactory::newDlg(const string& name)
205 206
     if(mod_it == mod_reg.end()){
206 207
 	ERROR("Unknown script name\n");
207 208
 	throw AmSession::Exception(500,"Unknown Application");
208
-	return NULL;
209 209
     }
210 210
 
211 211
     IvrScriptDesc& mod_desc = mod_it->second;
212 212
 
213
-    IvrDialog* dlg = new IvrDialog();
213
+    AmDynInvoke* user_timer = user_timer_fact->getInstance();
214
+    if(!user_timer){
215
+	ERROR("could not get a user timer reference\n");
216
+	throw AmSession::Exception(500,"could not get a user timer reference");
217
+    }
218
+	
219
+
220
+    IvrDialog* dlg = new IvrDialog(user_timer);
214 221
 
215 222
     PyObject* c_dlg = PyCObject_FromVoidPtr(dlg,NULL);
216 223
     PyObject* dlg_inst = PyObject_CallMethod(mod_desc.dlg_class,"__new__","OO",
... ...
@@ -318,6 +325,14 @@ bool IvrFactory::loadScript(const string& path)
318 325
  */
319 326
 int IvrFactory::onLoad()
320 327
 {
328
+    user_timer_fact = AmPlugIn::instance()->getFactory4Di("user_timer");
329
+    if(!user_timer_fact){
330
+	
331
+	ERROR("could not load user_timer from session_timer plug-in\n");
332
+	return -1;
333
+    }
334
+
335
+
321 336
     AmConfigReader cfg;
322 337
 
323 338
     if(cfg.loadFile(add2path(AmConfig::ModConfigPath,1,MOD_NAME ".conf")))
... ...
@@ -403,10 +418,11 @@ AmSession* IvrFactory::onInvite(const AmSipRequest& req)
403 418
 	return newDlg(req.user);
404 419
 }
405 420
 
406
-IvrDialog::IvrDialog()
421
+IvrDialog::IvrDialog(AmDynInvoke* user_timer)
407 422
     : py_mod(NULL), 
408 423
       py_dlg(NULL),
409
-      playlist(this)
424
+      playlist(this),
425
+      user_timer(user_timer)
410 426
 {
411 427
     sip_relay_only = false;
412 428
 }
... ...
@@ -501,12 +517,13 @@ void IvrDialog::process(AmEvent* event)
501 517
 	event->processed = true;
502 518
     }
503 519
     
504
-    AmTimeoutEvent* timeout_event = dynamic_cast<AmTimeoutEvent*>(event);
505
-    if(timeout_event && timeout_event->event_id > 0) {
520
+    AmPluginEvent* plugin_event = dynamic_cast<AmPluginEvent*>(event);
521
+    if(plugin_event && plugin_event->name == "timer_timeout") {
506 522
 	PYLOCK;
507
-	callPyEventHandler("onTimer", timeout_event->event_id);
523
+	callPyEventHandler("onTimer", plugin_event->data.get(0).asInt());
508 524
 	event->processed = true;
509 525
     }
526
+
510 527
     if (!event->processed)
511 528
       AmB2BCallerSession::process(event);
512 529
 
... ...
@@ -44,27 +44,21 @@ struct IvrScriptDesc
44 44
 {
45 45
     PyObject* mod;
46 46
     PyObject* dlg_class;
47
-    // PyObject* config;
48 47
 
49 48
     IvrScriptDesc()
50 49
 	: mod(0), 
51
-	  dlg_class(0)// ,
52
-// 	  config(0)
50
+	  dlg_class(0)
53 51
     {}
54 52
 
55 53
     IvrScriptDesc(const IvrScriptDesc& d)
56 54
 	: mod(d.mod), 
57
-	  dlg_class(d.dlg_class)// ,
58
-// 	  config(d.config)
55
+	  dlg_class(d.dlg_class)
59 56
     {}
60 57
 
61 58
     IvrScriptDesc(PyObject* mod, 
62
-		  PyObject* dlg_class// ,
63
-// 		  PyObject* config
64
-		  )
59
+		  PyObject* dlg_class)
65 60
 	: mod(mod),
66
-	  dlg_class(dlg_class)// ,
67
-// 	  config(config)
61
+	  dlg_class(dlg_class)
68 62
     {}
69 63
 };
70 64
 
... ...
@@ -77,6 +71,8 @@ class IvrFactory: public AmSessionFactory
77 71
 
78 72
     map<string,IvrScriptDesc> mod_reg;
79 73
 
74
+    AmDynInvokeFactory* user_timer_fact;
75
+
80 76
     void init_python_interpreter();
81 77
     void import_ivr_builtins();
82 78
 
... ...
@@ -112,9 +108,10 @@ class IvrDialog : public AmB2BCallerSession
112 108
     void process(AmEvent* event);
113 109
 
114 110
 public:
111
+    AmDynInvoke* user_timer;
115 112
     AmPlaylist playlist;
116 113
 
117
-    IvrDialog();
114
+    IvrDialog(AmDynInvoke* user_timer);
118 115
     ~IvrDialog();
119 116
 
120 117
     // must be called before everything else.
... ...
@@ -4,7 +4,7 @@
4 4
 
5 5
 #include "IvrSipDialog.h"
6 6
 
7
-#include "AmSessionTimer.h"
7
+//#include "AmSessionTimer.h"
8 8
 
9 9
 // Data definition
10 10
 typedef struct {
... ...
@@ -290,8 +290,13 @@ static PyObject* IvrDialogBase_setTimer(IvrDialogBase* self, PyObject* args)
290 290
       return NULL;
291 291
     }
292 292
 
293
-    AmSessionTimer::instance()->
294
-      setTimer(id, interval, self->p_dlg->getLocalTag());
293
+    AmArgArray di_args,ret;
294
+    di_args.push(id);
295
+    di_args.push(interval);
296
+    di_args.push(self->p_dlg->getLocalTag().c_str());
297
+
298
+    self->p_dlg->user_timer->
299
+	invoke("setTimer", di_args, ret);
295 300
     
296 301
     Py_INCREF(Py_None);
297 302
     return Py_None;
... ...
@@ -310,8 +315,12 @@ static PyObject* IvrDialogBase_removeTimer(IvrDialogBase* self, PyObject* args)
310 315
       return NULL;
311 316
     }
312 317
 
313
-    AmSessionTimer::instance()->
314
-      removeTimer(id, self->p_dlg->getLocalTag());
318
+    AmArgArray di_args,ret;
319
+    di_args.push(id);
320
+    di_args.push(self->p_dlg->getLocalTag().c_str());
321
+
322
+    self->p_dlg->user_timer->
323
+      invoke("removeTimer",di_args,ret);
315 324
     
316 325
     Py_INCREF(Py_None);
317 326
     return Py_None;
... ...
@@ -322,8 +331,11 @@ static PyObject* IvrDialogBase_removeTimers(IvrDialogBase* self, PyObject* args)
322 331
 {
323 332
     assert(self->p_dlg);
324 333
     
325
-    AmSessionTimer::instance()->
326
-      removeUserTimers(self->p_dlg->getLocalTag());
334
+    AmArgArray di_args,ret;
335
+    di_args.push(self->p_dlg->getLocalTag().c_str());
336
+
337
+    self->p_dlg->user_timer->
338
+      invoke("removeUserTimers",di_args,ret);
327 339
     
328 340
     Py_INCREF(Py_None);
329 341
     return Py_None;
... ...
@@ -1,6 +1,7 @@
1 1
 #include "IvrSipDialog.h"
2
-#include "AmSessionTimer.h"
2
+//#include "AmSessionTimer.h"
3 3
 #include "AmSipDialog.h"
4
+#include "log.h"
4 5
 
5 6
 // Data definition
6 7
 typedef struct {
... ...
@@ -1,5 +1,5 @@
1 1
 #include "IvrSipRequest.h"
2
-#include "AmSessionTimer.h"
2
+//#include "AmSessionTimer.h"
3 3
 #include "AmSipRequest.h"
4 4
 
5 5
 #if 0
... ...
@@ -29,6 +29,19 @@
29 29
 #include "log.h"
30 30
 #include "AmSession.h"
31 31
 
32
+AmDynInvoke::AmDynInvoke() {}
33
+AmDynInvoke::~AmDynInvoke() {}
34
+
35
+void AmDynInvoke::invoke(const string& method, const AmArgArray& args, AmArgArray& ret)
36
+{
37
+    throw NotImplemented(method);
38
+}
39
+
40
+AmDynInvokeFactory::AmDynInvokeFactory(const string& name)
41
+    : AmPluginFactory(name) 
42
+{
43
+}
44
+
32 45
 AmSessionFactory::AmSessionFactory(const string& name)
33 46
   : AmPluginFactory(name), mod_conf(AmConfig::defaultSessionTimerConfig)
34 47
 {
... ...
@@ -27,19 +27,36 @@
27 27
 #ifndef _AmApi_h_
28 28
 #define _AmApi_h_
29 29
 
30
-//#include "AmRequest.h"
31 30
 #include "AmThread.h"
32 31
 #include "AmSipRequest.h"
33 32
 #include "AmConfig.h"
33
+#include "AmArg.h"
34 34
 
35 35
 #include <string>
36 36
 #include <map>
37 37
 using std::map;
38 38
 using std::string;
39 39
 
40
-class AmSession;
41
-class AmSessionEventHandler;
40
+/**
41
+ * Multi-purpose plugin class
42
+ */
43
+class AmDynInvoke
44
+{
45
+public:
46
+    struct NotImplemented {
47
+	string what;
48
+	NotImplemented(const string& w)
49
+	    : what(w) {}
50
+    };
51
+
52
+    AmDynInvoke();
53
+    virtual ~AmDynInvoke();
54
+    virtual void invoke(const string& method, const AmArgArray& args, AmArgArray& ret);
55
+};
42 56
 
57
+/**
58
+ * Base class for plugin factories
59
+ */
43 60
 class AmPluginFactory
44 61
 {
45 62
     string plugin_name;
... ...
@@ -61,6 +78,33 @@ public:
61 78
     virtual int onLoad()=0;
62 79
 };
63 80
 
81
+/**
82
+ * Factory for multi-purpose plugin classes
83
+ */
84
+class AmDynInvokeFactory: public AmPluginFactory
85
+{
86
+public:
87
+    AmDynInvokeFactory(const string& name);
88
+    virtual AmDynInvoke* getInstance()=0;
89
+};
90
+
91
+
92
+class AmSession;
93
+class AmSessionEventHandler;
94
+
95
+class AmSessionEventHandlerFactory: public AmPluginFactory
96
+{
97
+public:
98
+    AmSessionEventHandlerFactory(const string& name);
99
+
100
+    virtual AmSessionEventHandler* getHandler(AmSession*)=0;
101
+
102
+    /**
103
+     * @return true if session creation should be stopped
104
+     */
105
+    virtual bool onInvite(const AmSipRequest& req)=0;
106
+};
107
+
64 108
 
65 109
 class AmSessionFactory: public AmPluginFactory
66 110
 {
... ...
@@ -68,11 +112,11 @@ class AmSessionFactory: public AmPluginFactory
68 112
   AmSessionTimerConfig mod_conf;
69 113
 
70 114
 protected:
71
-  /**
72
-   * This reads the module configuration from 
73
-   * cfg into the modules mod_conf.
74
-   */
75
-  int configureModule(AmConfigReader& cfg);
115
+    /**
116
+     * This reads the module configuration from 
117
+     * cfg into the modules mod_conf.
118
+     */
119
+    int configureModule(AmConfigReader& cfg);
76 120
 
77 121
 public:
78 122
     /**
... ...
@@ -93,18 +137,6 @@ public:
93 137
     virtual AmSession* onInvite(const AmSipRequest& req)=0;
94 138
 };
95 139
 
96
-class AmSessionEventHandlerFactory: public AmPluginFactory
97
-{
98
-public:
99
-    AmSessionEventHandlerFactory(const string& name);
100
-
101
-    virtual AmSessionEventHandler* getHandler(AmSession*)=0;
102
-
103
-    /**
104
-     * @return true if session creation should be stopped
105
-     */
106
-    virtual bool onInvite(const AmSipRequest& req)=0;
107
-};
108 140
 
109 141
 #define EXPORT_FACTORY(fctname,class_name,...) \
110 142
             extern "C" void* fctname()\
... ...
@@ -129,6 +161,12 @@ typedef void* (*FactoryCreate)();
129 161
 #define EXPORT_SESSION_EVENT_HANDLER_FACTORY(class_name,app_name) \
130 162
             EXPORT_FACTORY(FACTORY_SESSION_EVENT_HANDLER_EXPORT,class_name,app_name)
131 163
 
164
+#define FACTORY_PLUGIN_CLASS_EXPORT     plugin_class_create
165
+#define FACTORY_PLUGIN_CLASS_EXPORT_STR XSTR(FACTORY_PLUGIN_CLASS_EXPORT)
166
+
167
+#define EXPORT_PLUGIN_CLASS_FACTORY(class_name,app_name) \
168
+            EXPORT_FACTORY(FACTORY_PLUGIN_CLASS_EXPORT,class_name,app_name)
169
+
132 170
 #endif
133 171
 // Local Variables:
134 172
 // mode:C++
135 173
new file mode 100644
... ...
@@ -0,0 +1,88 @@
1
+#ifndef _AmArg_h_
2
+#define _AmArg_h_
3
+
4
+#include <assert.h>
5
+
6
+#include <vector>
7
+using std::vector;
8
+
9
+class AmArg
10
+{
11
+public:
12
+    // type enum
13
+    enum {
14
+	Undef=0,
15
+
16
+	Int,
17
+	Double,
18
+	CStr
19
+    };
20
+
21
+private:
22
+    // type
23
+    short type;
24
+    
25
+    // value
26
+    union {
27
+	
28
+	int         v_int;
29
+	double      v_double;
30
+	const char* v_cstr;
31
+    };
32
+
33
+public:
34
+    AmArg(const AmArg& v)
35
+	: type(v.type){
36
+	
37
+	switch(type){
38
+	case Int: v_int = v.v_int; break;
39
+	case Double: v_double = v.v_double; break;
40
+	case CStr: v_cstr = v.v_cstr; break;
41
+	default: assert(0);
42
+	}
43
+    }
44
+
45
+    AmArg(const int& v)
46
+	: type(Int),
47
+	  v_int(v)
48
+    {}
49
+
50
+    AmArg(const double& v)
51
+	: type(Double),
52
+	  v_double(v)
53
+    {}
54
+
55
+    AmArg(const char* v)
56
+	: type(CStr),
57
+	  v_cstr(v)
58
+    {}
59
+
60
+    short getType() const { return type; }
61
+
62
+    int         asInt()    const { return v_int; }
63
+    double      asDouble() const { return v_double; }
64
+    const char* asCStr()   const { return v_cstr; }
65
+};
66
+
67
+class AmArgArray
68
+{
69
+    vector<AmArg> v;
70
+
71
+public:
72
+    AmArgArray() : v() {}
73
+    AmArgArray(const AmArgArray& a) : v(a.v) {}
74
+    
75
+    void push(const AmArg& a){
76
+	v.push_back(a);
77
+    }
78
+
79
+    const AmArg& get(size_t idx) const {
80
+	
81
+	assert(idx < v.size());
82
+	return v[idx];
83
+    }
84
+
85
+    size_t size() { return v.size(); }
86
+};
87
+
88
+#endif
... ...
@@ -1,6 +1,13 @@
1 1
 #ifndef AmEvent_h
2 2
 #define AmEvent_h
3 3
 
4
+#include "AmArg.h"
5
+
6
+#include <string>
7
+using std::string;
8
+
9
+#define E_PLUGIN 100
10
+
4 11
 struct AmEvent
5 12
 {
6 13
     int event_id;
... ...
@@ -10,6 +17,20 @@ struct AmEvent
10 17
     virtual ~AmEvent();
11 18
 };
12 19
 
20
+struct AmPluginEvent: public AmEvent
21
+{
22
+    string      name;
23
+    AmArgArray  data;
24
+
25
+    AmPluginEvent(const string& n)
26
+	: AmEvent(E_PLUGIN), name(n), data() {}
27
+
28
+    AmPluginEvent(const string& n, const AmArgArray& d)
29
+	: AmEvent(E_PLUGIN), name(n), data(d) {}
30
+};
31
+
32
+
33
+
13 34
 class AmEventHandler
14 35
 {
15 36
 public:
... ...
@@ -123,6 +123,13 @@ int AmPlugIn::load(const string& directory)
123 123
 	if(err)
124 124
 	    break;
125 125
     }
126
+
127
+    for(map<string,AmDynInvokeFactory*>::iterator it = name2di.begin();
128
+	it != name2di.end(); it++){
129
+	err = it->second->onLoad();
130
+	if(err)
131
+	    break;
132
+    }
126 133
     
127 134
     map<string,AmSessionFactory*> apps(name2app);
128 135
     for(map<string,AmSessionFactory*>::iterator it = apps.begin();
... ...
@@ -149,6 +156,7 @@ int AmPlugIn::loadPlugIn(const string& file)
149 156
     FactoryCreate fc = NULL;
150 157
     amci_exports_t* exports = (amci_exports_t*)dlsym(h_dl,"amci_exports");
151 158
 
159
+    bool has_sym=false;
152 160
     if(exports){
153 161
  	if(loadAudioPlugIn(exports))
154 162
 	    goto error;
... ...
@@ -158,12 +166,20 @@ int AmPlugIn::loadPlugIn(const string& file)
158 166
     if((fc = (FactoryCreate)dlsym(h_dl,FACTORY_SESSION_EXPORT_STR)) != NULL){
159 167
 	if(loadAppPlugIn((AmPluginFactory*)fc()))
160 168
 	    goto error;
169
+	has_sym=true;
161 170
     }
162
-    else if((fc = (FactoryCreate)dlsym(h_dl,FACTORY_SESSION_EVENT_HANDLER_EXPORT_STR)) != NULL){
171
+    if((fc = (FactoryCreate)dlsym(h_dl,FACTORY_SESSION_EVENT_HANDLER_EXPORT_STR)) != NULL){
163 172
 	if(loadSehPlugIn((AmPluginFactory*)fc()))
164 173
 	    goto error;
174
+	has_sym=true;
165 175
     }
166
-    else {
176
+    if((fc = (FactoryCreate)dlsym(h_dl,FACTORY_PLUGIN_CLASS_EXPORT_STR)) != NULL){
177
+	if(loadDiPlugIn((AmPluginFactory*)fc()))
178
+	    goto error;
179
+	has_sym=true;
180
+    }
181
+
182
+    if(!has_sym){
167 183
 	ERROR("Plugin type could not be detected (%s)(%s)\n",file.c_str(),dlerror());
168 184
 	goto error;
169 185
     }
... ...
@@ -251,6 +267,14 @@ AmSessionEventHandlerFactory* AmPlugIn::getFactory4Seh(const string& name)
251 267
   return 0;
252 268
 }
253 269
 
270
+AmDynInvokeFactory* AmPlugIn::getFactory4Di(const string& name)
271
+{
272
+  map<string,AmDynInvokeFactory*>::iterator it = name2di.find(name);
273
+  if(it != name2di.end())
274
+    return it->second;
275
+  return 0;
276
+}
277
+
254 278
 int AmPlugIn::loadAudioPlugIn(amci_exports_t* exports)
255 279
 {
256 280
     if(!exports){
... ...
@@ -299,13 +323,8 @@ int AmPlugIn::loadAppPlugIn(AmPluginFactory* f)
299 323
         goto error;
300 324
     }
301 325
       
302
-    //if(!sf->onLoad()){
303
-	name2app.insert(std::make_pair(sf->getName(),sf));
304
-	DBG("application '%s' loaded.\n",sf->getName().c_str());
305
-//     }
306
-//     else {
307
-// 	goto error;
308
-//     }
326
+    name2app.insert(std::make_pair(sf->getName(),sf));
327
+    DBG("application '%s' loaded.\n",sf->getName().c_str());
309 328
 
310 329
     return 0;
311 330
 
... ...
@@ -326,13 +345,30 @@ int AmPlugIn::loadSehPlugIn(AmPluginFactory* f)
326 345
         goto error;
327 346
     }
328 347
       
329
-//     if(!sf->onLoad()){
330
-	name2seh.insert(std::make_pair(sf->getName(),sf));
331
-	DBG("session component '%s' loaded.\n",sf->getName().c_str());
332
-//     }
333
-//     else {
334
-// 	goto error;
335
-//     }
348
+    name2seh.insert(std::make_pair(sf->getName(),sf));
349
+    DBG("session component '%s' loaded.\n",sf->getName().c_str());
350
+
351
+    return 0;
352
+
353
+ error:
354
+    return -1;
355
+}
356
+
357
+int AmPlugIn::loadDiPlugIn(AmPluginFactory* f)
358
+{
359
+    AmDynInvokeFactory* sf = dynamic_cast<AmDynInvokeFactory*>(f);
360
+    if(!sf){
361
+        ERROR("invalid component plug-in!\n");
362
+        goto error;
363
+    }
364
+
365
+    if(name2di.find(sf->getName()) != name2di.end()){
366
+        ERROR("component '%s' already loaded !\n",sf->getName().c_str());
367
+        goto error;
368
+    }
369
+      
370
+    name2di.insert(std::make_pair(sf->getName(),sf));
371
+    DBG("component '%s' loaded.\n",sf->getName().c_str());
336 372
 
337 373
     return 0;
338 374
 
... ...
@@ -38,6 +38,7 @@ using std::vector;
38 38
 class AmPluginFactory;
39 39
 class AmSessionFactory;
40 40
 class AmSessionEventHandlerFactory;
41
+class AmDynInvokeFactory;
41 42
 
42 43
 struct amci_exports_t;
43 44
 struct amci_codec_t;
... ...
@@ -67,6 +68,7 @@ private:
67 68
     map<string,AmSessionFactory*>  name2app;
68 69
 
69 70
     map<string,AmSessionEventHandlerFactory*> name2seh;
71
+    map<string,AmDynInvokeFactory*> name2di;
70 72
 
71 73
     int dynamic_pl; // range: 96->127, see RFC 1890
72 74
     
... ...
@@ -78,6 +80,7 @@ private:
78 80
     int loadAudioPlugIn(amci_exports_t* exports);
79 81
     int loadAppPlugIn(AmPluginFactory* cb);
80 82
     int loadSehPlugIn(AmPluginFactory* cb);
83
+    int loadDiPlugIn(AmPluginFactory* cb);
81 84
 
82 85
     int addCodec(amci_codec_t* c);
83 86
     int addPayload(amci_payload_t* p);
... ...
@@ -136,6 +139,11 @@ private:
136 139
      */
137 140
     AmSessionEventHandlerFactory* getFactory4Seh(const string& name);
138 141
 
142
+    /**
143
+     * Dynamic invokation component
144
+     */
145
+    AmDynInvokeFactory* getFactory4Di(const string& name);
146
+
139 147
     /** @return true if this record has been inserted. */
140 148
     bool registerFactory4App(const string& app_name, AmSessionFactory* f);
141 149
 };
... ...
@@ -38,7 +38,7 @@
38 38
 #include "AmSessionScheduler.h"
39 39
 #include "AmDtmfDetector.h"
40 40
 /* Session Timer: -ssa */
41
-#include "AmSessionTimer.h"
41
+//#include "AmSessionTimer.h"
42 42
 
43 43
 #include "log.h"
44 44
 
... ...
@@ -315,7 +315,7 @@ void AmSession::run()
315 315
 		}
316 316
 	    }
317 317
 	    // remove pending timers
318
-	    AmSessionTimer::instance()->removeTimers(getLocalTag());
318
+	    //AmSessionTimer::instance()->removeTimers(getLocalTag());
319 319
 	}
320 320
 	catch(const AmSession::Exception& e){ throw e; }
321 321
 	catch(const string& str){
... ...
@@ -555,10 +555,10 @@ int AmSession::acceptAudio(const AmSipRequest& req)
555 555
     return -1;
556 556
 }
557 557
 
558
-string AmSession::SessionTimerException::getErrorHeaders() const {
559
-  return "Min-SE:" + int2str(minSE) + "\n"
560
-    + "Supported: timer\n";
561
-}
558
+// string AmSession::SessionTimerException::getErrorHeaders() const {
559
+//   return "Min-SE:" + int2str(minSE) + "\n"
560
+//     + "Supported: timer\n";
561
+// }
562 562
 
563 563
 void AmSession::onSendRequest(const string& method, const string& content_type,
564 564
 			      const string& body, string& hdrs)
... ...
@@ -53,13 +53,6 @@ class AmSessionFactory;
53 53
 //class AmDialogState;
54 54
 class AmDtmfEvent;
55 55
 
56
-/* Session Timer: -ssa */
57
-class AmTimeoutEvent;
58
-// these are the timer IDs for session timer
59
-// Caution: do not use these for other purposes
60
-#define ID_SESSION_INTERVAL_TIMER -1
61
-#define ID_SESSION_REFRESH_TIMER  -2
62
-
63 56
 
64 57
 /**
65 58
  *  Signaling plugins must inherite from this class.
... ...
@@ -153,15 +146,15 @@ public:
153 146
 	Exception(int c, string r) : code(c), reason(r) {}
154 147
     };
155 148
 
156
-    struct SessionTimerException : Exception {
157
-      unsigned int minSE;
149
+//     struct SessionTimerException : Exception {
150
+//       unsigned int minSE;
158 151
 
159
-      SessionTimerException(unsigned int min_SE) 
160
-	: Exception(422, "Session Interval Too Small"), 
161
-	  minSE(min_SE) { }
152
+//       SessionTimerException(unsigned int min_SE) 
153
+// 	: Exception(422, "Session Interval Too Small"), 
154
+// 	  minSE(min_SE) { }
162 155
 
163
-      string getErrorHeaders() const;
164
-    };
156
+//       string getErrorHeaders() const;
157
+//     };
165 158
 
166 159
     /** 
167 160
      * Session constructor.
... ...
@@ -185,10 +185,10 @@ void AmSessionContainer::startSessionUAS(AmSipRequest& req)
185 185
 	    //throw AmSession::Exception(500,"internal error");
186 186
 	}
187 187
     } 
188
-    catch(const AmSession::SessionTimerException& e){
189
- 	ERROR("%i %s\n",e.code,e.reason.c_str());
190
-	AmSipDialog::reply_error(req,e.code,e.reason,e.getErrorHeaders());
191
-    }
188
+//     catch(const AmSession::SessionTimerException& e){
189
+//  	ERROR("%i %s\n",e.code,e.reason.c_str());
190
+// 	AmSipDialog::reply_error(req,e.code,e.reason,e.getErrorHeaders());
191
+//     }
192 192
     catch(const AmSession::Exception& e){
193 193
  	ERROR("%i %s\n",e.code,e.reason.c_str());
194 194
 	AmSipDialog::reply_error(req,e.code,e.reason);
... ...
@@ -56,8 +56,6 @@ int EchoFactory::onLoad()
56 56
 
57 57
 AmSession* EchoFactory::onInvite(const AmSipRequest& req)
58 58
 {
59
-//     if()
60
-
61 59
     AmSession* s = new EchoDialog();
62 60
     s->addHandler(session_timer_f->getHandler(s));
63 61
 
... ...
@@ -1,6 +1,6 @@
1 1
 #include "SessionTimer.h"
2 2
 #include "AmUtils.h"
3
-#include "AmSessionTimer.h"
3
+#include "UserTimer.h"
4 4
 
5 5
 EXPORT_SESSION_EVENT_HANDLER_FACTORY(SessionTimerFactory, MOD_NAME);
6 6
 
... ...
@@ -34,7 +34,7 @@ bool SessionTimer::process(AmEvent* ev)
34 34
     /* Session Timer: -ssa */
35 35
     AmTimeoutEvent* timeout_ev = dynamic_cast<AmTimeoutEvent*>(ev);
36 36
     if (timeout_ev) {
37
-	DBG("received timeout Event with ID %d\n", ev->event_id);
37
+	DBG("received timeout Event with ID %d\n", timeout_ev->data.get(0).asInt());
38 38
 	onTimeoutEvent(timeout_ev);
39 39
 	return true;
40 40
     }
... ...
@@ -264,23 +264,23 @@ void SessionTimer::setTimers(AmSession* s)
264 264
     DBG("Setting session interval timer: %ds, tag '%s'\n", session_interval, 
265 265
 	s->getLocalTag().c_str());
266 266
 
267
-    AmSessionTimer::instance()->
267
+    UserTimer::instance()->
268 268
       setTimer(ID_SESSION_INTERVAL_TIMER, session_interval, s->getLocalTag());
269 269
     
270 270
     // set session refresh action timer, after half the expiration
271 271
     if (session_refresher == refresh_local) {
272
-    DBG("Setting session refresh timer: %ds, tag '%s'\n", session_interval/2, 
273
-	s->getLocalTag().c_str());
274
-      AmSessionTimer::instance()->
275
-	setTimer(ID_SESSION_REFRESH_TIMER, session_interval/2, s->getLocalTag());
272
+	DBG("Setting session refresh timer: %ds, tag '%s'\n", session_interval/2, 
273
+	    s->getLocalTag().c_str());
274
+	UserTimer::instance()->
275
+	    setTimer(ID_SESSION_REFRESH_TIMER, session_interval/2, s->getLocalTag());
276 276
     }
277 277
 }
278 278
 
279 279
 void SessionTimer::removeTimers(AmSession* s) 
280 280
 {
281
-  AmSessionTimer::instance()->
281
+  UserTimer::instance()->
282 282
     removeTimer(ID_SESSION_REFRESH_TIMER, s->getLocalTag());
283
-  AmSessionTimer::instance()->
283
+  UserTimer::instance()->
284 284
     removeTimer(ID_SESSION_INTERVAL_TIMER, s->getLocalTag());
285 285
 }
286 286
 
... ...
@@ -288,13 +288,14 @@ void SessionTimer::onTimeoutEvent(AmTimeoutEvent* timeout_ev)
288 288
 {
289 289
 //   if (!session_timer_conf.getEnableSessionTimer())
290 290
 //     return;
291
-  
292
-    if (timeout_ev->event_id == ID_SESSION_REFRESH_TIMER) {
291
+    int timer_id = timeout_ev->data.get(0).asInt();
292
+
293
+    if (timer_id == ID_SESSION_REFRESH_TIMER) {
293 294
 	if (session_refresher == refresh_local)
294 295
 	    s->sendReinvite();
295 296
 	else
296 297
 	    WARN("need session refresh but remote session is refresher\n");
297
-    } else if (timeout_ev->event_id == ID_SESSION_INTERVAL_TIMER) {
298
+    } else if (timer_id == ID_SESSION_INTERVAL_TIMER) {
298 299
 //     // let the session know it got timeout
299 300
 //     onTimeout();
300 301
 	
... ...
@@ -6,6 +6,14 @@
6 6
 
7 7
 #define MOD_NAME "session_timer"
8 8
 
9
+/* Session Timer: -ssa */
10
+class AmTimeoutEvent;
11
+// these are the timer IDs for session timer
12
+// Caution: do not use these for other purposes
13
+#define ID_SESSION_INTERVAL_TIMER -1
14
+#define ID_SESSION_REFRESH_TIMER  -2
15
+
16
+
9 17
 class SessionTimerFactory: public AmSessionEventHandlerFactory
10 18
 {
11 19
     bool checkSessionExpires(const AmSipRequest& req);
12 20
similarity index 60%
13 21
rename from core/AmSessionTimer.cpp
14 22
rename to core/plug-in/session_timer/UserTimer.cpp
... ...
@@ -1,37 +1,64 @@
1 1
 
2
-#include "AmSessionTimer.h"
2
+#include "UserTimer.h"
3 3
 
4 4
 #include <sys/time.h>
5 5
 
6 6
 #define SESSION_TIMER_GRANULARITY 100 // check every 100 millisec
7 7
 
8
+class UserTimerFactory: public AmDynInvokeFactory
9
+{
10
+public:
11
+    UserTimerFactory(const string& name)
12
+	: AmDynInvokeFactory(name) {}
13
+
14
+    AmDynInvoke* getInstance(){
15
+	return UserTimer::instance();
16
+    }
17
+
18
+    int onLoad(){
19
+#ifdef SESSION_TIMER_THREAD
20
+	UserTimer::instance()->start();
21
+#endif
22
+	return 0;
23
+    }
24
+};
25
+
26
+
27
+EXPORT_PLUGIN_CLASS_FACTORY(UserTimerFactory,"user_timer");
28
+
29
+AmTimeoutEvent::AmTimeoutEvent(int timer_id)
30
+    : AmPluginEvent(TIMEOUTEVENT_NAME)
31
+{
32
+    data.push(AmArg(timer_id));
33
+}
34
+
8 35
 
9
-AmSessionTimer::AmSessionTimer()
36
+UserTimer::UserTimer()
10 37
 {
11 38
 }
12 39
 
13
-AmSessionTimer::~AmSessionTimer()
40
+UserTimer::~UserTimer()
14 41
 {
15 42
 }
16 43
 
17
-AmSessionTimer* AmSessionTimer::_instance=0;
44
+UserTimer* UserTimer::_instance=0;
18 45
 
19
-AmSessionTimer* AmSessionTimer::instance()
46
+UserTimer* UserTimer::instance()
20 47
 {
21 48
     if(!_instance)
22
-	_instance = new AmSessionTimer();
49
+	_instance = new UserTimer();
23 50
     return _instance;
24 51
 }
25 52
 
26 53
 #ifdef SESSION_TIMER_THREAD
27
-void AmSessionTimer::run() {
54
+void UserTimer::run() {
28 55
     while(1){
29 56
 	usleep(SESSION_TIMER_GRANULARITY * 1000);
30 57
         checkTimers();
31 58
     }
32 59
 }
33 60
 
34
-void AmSessionTimer::on_stop() {
61
+void UserTimer::on_stop() {
35 62
 }
36 63
 #endif // SESSION_TIMER_THREAD
37 64
 
... ...
@@ -45,7 +72,7 @@ bool operator == (const AmTimer& l, const AmTimer& r)
45 72
   return l.id == r.id;
46 73
 }
47 74
 
48
-void AmSessionTimer::checkTimers() {
75
+void UserTimer::checkTimers() {
49 76
   timers_mut.lock();
50 77
   if(timers.empty()){
51 78
     timers_mut.unlock();
... ...
@@ -68,7 +95,9 @@ void AmSessionTimer::checkTimers() {
68 95
 						   new AmTimeoutEvent(id))) {
69 96
       DBG("Timeout Event could not be posted, session does not exist any more.\n");
70 97
     }
71
-    
98
+    else {
99
+	DBG("Timeout Event could be posted.\n");
100
+    }
72 101
     
73 102
     if(timers.empty()) break;
74 103
     it = timers.begin();
... ...
@@ -76,7 +105,7 @@ void AmSessionTimer::checkTimers() {
76 105
   timers_mut.unlock();
77 106
 }
78 107
 
79
-void AmSessionTimer::setTimer(int id, int seconds, const string& session_id) {
108
+void UserTimer::setTimer(int id, int seconds, const string& session_id) {
80 109
     struct timeval tval;
81 110
     gettimeofday(&tval,NULL);
82 111
 
... ...
@@ -84,7 +113,7 @@ void AmSessionTimer::setTimer(int id, int seconds, const string& session_id) {
84 113
     setTimer(id, &tval, session_id);
85 114
 }
86 115
 
87
-void AmSessionTimer::setTimer(int id, struct timeval* t, 
116
+void UserTimer::setTimer(int id, struct timeval* t, 
88 117
 			      const string& session_id) 
89 118
 {
90 119
   timers_mut.lock();
... ...
@@ -99,13 +128,13 @@ void AmSessionTimer::setTimer(int id, struct timeval* t,
99 128
 }
100 129
 
101 130
 
102
-void AmSessionTimer::removeTimer(int id, const string& session_id) {
131
+void UserTimer::removeTimer(int id, const string& session_id) {
103 132
   timers_mut.lock();
104 133
   unsafe_removeTimer(id, session_id);
105 134
   timers_mut.unlock();
106 135
 }
107 136
 
108
-void AmSessionTimer::unsafe_removeTimer(int id, const string& session_id) 
137
+void UserTimer::unsafe_removeTimer(int id, const string& session_id) 
109 138
 {
110 139
   // erase old timer if exists
111 140
   set<AmTimer>::iterator it = timers.begin(); 
... ...
@@ -118,7 +147,7 @@ void AmSessionTimer::unsafe_removeTimer(int id, const string& session_id)
118 147
   }
119 148
 }
120 149
 
121
-void AmSessionTimer::removeTimers(const string& session_id) {
150
+void UserTimer::removeTimers(const string& session_id) {
122 151
   //  DBG("removing timers for <%s>\n", session_id.c_str());
123 152
   timers_mut.lock();
124 153
   for (set<AmTimer>::iterator it = timers.begin(); 
... ...
@@ -131,7 +160,7 @@ void AmSessionTimer::removeTimers(const string& session_id) {
131 160
   timers_mut.unlock();
132 161
 }
133 162
 
134
-void AmSessionTimer::removeUserTimers(const string& session_id) {
163
+void UserTimer::removeUserTimers(const string& session_id) {
135 164
   //  DBG("removing User timers for <%s>\n", session_id.c_str());
136 165
   timers_mut.lock();
137 166
   for (set<AmTimer>::iterator it = timers.begin(); 
... ...
@@ -143,3 +172,21 @@ void AmSessionTimer::removeUserTimers(const string& session_id) {
143 172
   }
144 173
   timers_mut.unlock();
145 174
 }
175
+
176
+void UserTimer::invoke(const string& method, const AmArgArray& args, AmArgArray& ret)
177
+{
178
+    if(method == "setTimer"){
179
+	setTimer(args.get(0).asInt(),
180
+		 args.get(1).asInt(),
181
+		 args.get(2).asCStr());
182
+    }
183
+    else if(method == "removeTimer"){
184
+	removeTimer(args.get(0).asInt(),
185
+		    args.get(1).asCStr());
186
+    }
187
+    else if(method == "removeUserTimers"){
188
+	removeUserTimers(args.get(0).asCStr());
189
+    }
190
+    else
191
+	throw AmDynInvoke::NotImplemented(method);
192
+}
146 193
similarity index 79%
147 194
rename from core/AmSessionTimer.h
148 195
rename to core/plug-in/session_timer/UserTimer.h
... ...
@@ -1,4 +1,3 @@
1
-
2 1
 /*
3 2
  * Timer class with seconds granularity 
4 3
  */
... ...
@@ -19,12 +18,24 @@
19 18
 
20 19
 #include <set>
21 20
 
22
-class AmTimeoutEvent : public AmEvent {
21
+/**
22
+ * Timer Event: Name
23
+ */
24
+#define TIMEOUTEVENT_NAME "timer_timeout"
25
+
26
+/**
27
+ * Timer Event: class
28
+ * data[0]: int timer_id
29
+ */
30
+class AmTimeoutEvent : public AmPluginEvent 
31
+{
23 32
  public:
24
-  AmTimeoutEvent(int timer_id)
25
-    : AmEvent(timer_id) { }
33
+    AmTimeoutEvent(int timer_id);
26 34
 };
27 35
 
36
+/**
37
+ * Timer struct containing the alarm time.
38
+ */
28 39
 struct AmTimer
29 40
 {
30 41
   int id;
... ...
@@ -46,22 +57,22 @@ bool operator == (const AmTimer& l, const AmTimer& r);
46 57
  * Implements a timer with session granularity.
47 58
  * On timeout an AmTimeoutEvent with the ID is posted.
48 59
  */
49
-class AmSessionTimer 
60
+class UserTimer: public AmDynInvoke
50 61
 #ifdef SESSION_TIMER_THREAD
51
-: public AmThread
62
+,public AmThread
52 63
 #endif
53 64
 {
54
-  static AmSessionTimer* _instance;
65
+  static UserTimer* _instance;
55 66
 
56 67
   std::set<AmTimer> timers;
57 68
   AmMutex         timers_mut;
58 69
 
59 70
   void unsafe_removeTimer(int id, const string& session_id);
60 71
  public:
61
-  AmSessionTimer();
62
-  ~AmSessionTimer();
72
+  UserTimer();
73
+  ~UserTimer();
63 74
 
64
-  static AmSessionTimer* instance();
75
+  static UserTimer* instance();
65 76
 
66 77
   /** set timer with ID id, fire after s seconds event in 
67 78
       session session_id  */
... ...
@@ -84,6 +95,8 @@ class AmSessionTimer
84 95
   void run();
85 96
   void on_stop();
86 97
 #endif
98
+
99
+  void invoke(const string& method, const AmArgArray& args, AmArgArray& ret);
87 100
 };
88 101
 
89 102
 #endif //AM_SESSION_TIMER_H
... ...
@@ -38,7 +38,7 @@
38 38
 #include "AmSessionScheduler.h"
39 39
 #include "AmIcmpWatcher.h"
40 40
 #include "AmRtpReceiver.h"
41
-#include "AmSessionTimer.h"
41
+//#include "AmSessionTimer.h"
42 42
 
43 43
 #include "log.h"
44 44
 
... ...
@@ -412,8 +412,8 @@ int main(int argc, char* argv[])
412 412
     DBG("Starting RTP receiver\n");
413 413
     AmRtpReceiver::instance()->start();
414 414
 
415
-    DBG("Starting Session Timer\n");
416
-    AmSessionTimer::instance()->start();
415
+    //DBG("Starting Session Timer\n");
416
+    //AmSessionTimer::instance()->start();
417 417
 
418 418
     //DBG("Starting ICMP watcher\n");
419 419
     //AmIcmpWatcher::instance()->start();