Browse code

* introduces new plugin type: session-less ua behaviour can be implemented with a AmSIPEventHandler plugin, which receives replies to requests outside of a dialog.

* events can now be passed to session factories


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

Stefan Sayer authored on 04/12/2006 19:08:13
Showing 7 changed files
... ...
@@ -2,6 +2,7 @@
2 2
  * $Id$
3 3
  *
4 4
  * Copyright (C) 2002-2003 Fhg Fokus
5
+ * Copyright (C) 2006 iptego GmbH
5 6
  *
6 7
  * This file is part of sems, a free SIP media server.
7 8
  *
... ...
@@ -55,7 +56,18 @@ void AmSessionFactory::configureSession(AmSession* sess) {
55 56
     //SessionTimer::sess->configureSessionTimer(mod_conf);
56 57
 }
57 58
 
59
+void AmSessionFactory::postEvent(AmEvent* ev) {
60
+	ERROR("unhandled Event in %s module\n", getName().c_str());
61
+	delete ev;
62
+}
63
+
58 64
 AmSessionEventHandlerFactory::AmSessionEventHandlerFactory(const string& name)
59 65
 	: AmPluginFactory(name) 
60 66
 {
61 67
 }
68
+
69
+AmSIPEventHandler::AmSIPEventHandler(const string& name) 
70
+    : AmPluginFactory(name) 
71
+{
72
+}
73
+
... ...
@@ -2,6 +2,7 @@
2 2
  * $Id$
3 3
  *
4 4
  * Copyright (C) 2002-2003 Fhg Fokus
5
+ * Copyright (C) 2006 iptego GmbH
5 6
  *
6 7
  * This file is part of sems, a free SIP media server.
7 8
  *
... ...
@@ -29,6 +30,7 @@
29 30
 
30 31
 #include "AmThread.h"
31 32
 #include "AmSipRequest.h"
33
+#include "AmSipReply.h"
32 34
 #include "AmConfig.h"
33 35
 #include "AmArg.h"
34 36
 
... ...
@@ -141,8 +143,40 @@ public:
141 143
      *   processing as it would block the server.
142 144
      */
143 145
     virtual AmSession* onInvite(const AmSipRequest& req)=0;
146
+
147
+    /**
148
+     * method to receive an Event that is posted
149
+	 * to  the factory
150
+	 *
151
+     * Warning:
152
+     *   This method should not make any expensive
153
+     *   processing as it would block the thread 
154
+	 *   posting the event!
155
+     */
156
+    virtual void postEvent(AmEvent* ev);	
157
+
144 158
 };
145 159
 
160
+/** \brief Interface for plugins that implement session-less 
161
+ *     UA behaviour (e.g. registrar client, event notification 
162
+ *     client)
163
+ */
164
+class AmSIPEventHandler : public AmPluginFactory 
165
+{
166
+
167
+public:
168
+	AmSIPEventHandler(const string& name);
169
+	virtual ~AmSIPEventHandler() { }
170
+
171
+	/** will be called on incoming replies which do 
172
+	 *  not belong to a dialog of a session in the 
173
+	 *  SessionContainer.
174
+	 *
175
+	 *  @return true if reply was handled by plugin, false 
176
+	 *          otherwise
177
+	 */
178
+	virtual bool onSipReply(const AmSipReply& rep) = 0;
179
+};
146 180
 
147 181
 #if  __GNUC__ < 3
148 182
 #define EXPORT_FACTORY(fctname,class_name,args...) \
... ...
@@ -181,6 +215,12 @@ typedef void* (*FactoryCreate)();
181 215
 #define EXPORT_PLUGIN_CLASS_FACTORY(class_name,app_name) \
182 216
             EXPORT_FACTORY(FACTORY_PLUGIN_CLASS_EXPORT,class_name,app_name)
183 217
 
218
+#define FACTORY_SIP_EVENT_HANDLER_EXPORT     sip_evh_factory_create
219
+#define FACTORY_SIP_EVENT_HANDLER_EXPORT_STR XSTR(FACTORY_SIP_EVENT_HANDLER_EXPORT)
220
+
221
+#define EXPORT_SIP_EVENT_HANDLER_FACTORY(class_name,app_name) \
222
+            EXPORT_FACTORY(FACTORY_SIP_EVENT_HANDLER_EXPORT,class_name,app_name)
223
+
184 224
 #endif
185 225
 // Local Variables:
186 226
 // mode:C++
... ...
@@ -1,3 +1,31 @@
1
+/*
2
+ * $Id$
3
+ *
4
+ * Copyright (C) 2002-2003 Fhg Fokus
5
+ * Copyright (C) 2006 iptego GmbH
6
+ *
7
+ * This file is part of sems, a free SIP media server.
8
+ *
9
+ * sems is free software; you can redistribute it and/or modify
10
+ * it under the terms of the GNU General Public License as published by
11
+ * the Free Software Foundation; either version 2 of the License, or
12
+ * (at your option) any later version
13
+ *
14
+ * For a license to use the ser software under conditions
15
+ * other than those described here, or to purchase support for this
16
+ * software, please contact iptel.org by e-mail at the following addresses:
17
+ *    info@iptel.org
18
+ *
19
+ * sems is distributed in the hope that it will be useful,
20
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
+ * GNU General Public License for more details.
23
+ *
24
+ * You should have received a copy of the GNU General Public License 
25
+ * along with this program; if not, write to the Free Software 
26
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27
+ */
28
+
1 29
 #include "AmInterfaceHandler.h"
2 30
 #include "AmCtrlInterface.h"
3 31
 #include "AmSessionContainer.h"
... ...
@@ -228,16 +256,22 @@ int AmReplyHandler::handleRequest(AmCtrlInterface* ctrl)
228 256
 	return -1;
229 257
     }
230 258
 
231
-    AmSessionContainer::instance()->postEvent(
232
-	    reply.local_tag,
233
-	    new AmSipReplyEvent(reply));
234
-
235
-//     if(reply.code >= 200)
236
-// 	cleanup(ctrl);
259
+    if (!AmSessionContainer::instance()->postEvent(
260
+		   reply.local_tag,
261
+		   new AmSipReplyEvent(reply))) {
262
+		for (vector<AmSIPEventHandler*>::iterator it = 
263
+				 reply_handlers.begin(); it != reply_handlers.end(); it++)
264
+			if ((*it)->onSipReply(reply))
265
+				break;			
266
+	}
237 267
 
238 268
     return 0;
239 269
 }
240 270
 
271
+void AmReplyHandler::registerReplyHandler(AmSIPEventHandler* eh) {
272
+	reply_handlers.push_back(eh);
273
+}
274
+
241 275
 AmRequestHandlerFct* AmRequestHandler::getFct(const string& name)
242 276
 {
243 277
     AmRequestHandlerFct* fct=NULL;
... ...
@@ -1,3 +1,31 @@
1
+/*
2
+ * $Id$
3
+ *
4
+ * Copyright (C) 2002-2003 Fhg Fokus
5
+ * Copyright (C) 2006 iptego GmbH
6
+ *
7
+ * This file is part of sems, a free SIP media server.
8
+ *
9
+ * sems is free software; you can redistribute it and/or modify
10
+ * it under the terms of the GNU General Public License as published by
11
+ * the Free Software Foundation; either version 2 of the License, or
12
+ * (at your option) any later version
13
+ *
14
+ * For a license to use the ser software under conditions
15
+ * other than those described here, or to purchase support for this
16
+ * software, please contact iptel.org by e-mail at the following addresses:
17
+ *    info@iptel.org
18
+ *
19
+ * sems is distributed in the hope that it will be useful,
20
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
+ * GNU General Public License for more details.
23
+ *
24
+ * You should have received a copy of the GNU General Public License 
25
+ * along with this program; if not, write to the Free Software 
26
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27
+ */
28
+
1 29
 #ifndef AmInterfaceHandler_h
2 30
 #define AmInterfaceHandler_h
3 31
 
... ...
@@ -6,11 +34,15 @@
6 34
 
7 35
 #include <string>
8 36
 #include <map>
37
+#include <vector>
9 38
 
10 39
 using std::string;
11 40
 using std::map;
41
+using std::vector;
12 42
 
13 43
 class AmCtrlInterface;
44
+class AmSIPEventHandler;
45
+
14 46
 /** \brief interface of an InterfaceHandler */
15 47
 class AmInterfaceHandler
16 48
 {
... ...
@@ -69,19 +101,18 @@ class AmReplyHandler: public AmInterfaceHandler
69 101
     AmCtrlInterface* m_ctrl;
70 102
 
71 103
     AmReplyHandler(AmCtrlInterface* ctrl);
72
-//     void cleanup(AmCtrlInterface* ctrl);
104
+	vector<AmSIPEventHandler*> reply_handlers;
73 105
 
74 106
 public:
75 107
     static AmReplyHandler* get();
76 108
 
77 109
     AmCtrlInterface* getCtrl() { return m_ctrl; }
78
-
79
-//     AmCtrlInterface* getNewCtrl(const string& callid,
80
-// 				const string& remote_tag,
81
-// 				const string& local_tag,
82
-// 				int           cseq);
83 110
     
84 111
     int handleRequest(AmCtrlInterface* ctrl);
112
+
113
+	/** register a reply handler for incoming replies pertaining 
114
+	 * to a dialog without a session (not in SessionContainer) */
115
+	void registerReplyHandler(AmSIPEventHandler* eh);
85 116
 };
86 117
 
87 118
 #endif
... ...
@@ -2,6 +2,7 @@
2 2
  * $Id$
3 3
  *
4 4
  * Copyright (C) 2002-2003 Fhg Fokus
5
+ * Copyright (C) 2006 iptego GmbH
5 6
  *
6 7
  * This file is part of sems, a free SIP media server.
7 8
  *
... ...
@@ -28,6 +29,7 @@
28 29
 #include "AmPlugIn.h"
29 30
 #include "AmConfig.h"
30 31
 #include "AmApi.h"
32
+#include "AmInterfaceHandler.h"
31 33
 
32 34
 #include "amci/amci.h"
33 35
 #include "amci/codecs.h"
... ...
@@ -130,6 +132,17 @@ int AmPlugIn::load(const string& directory)
130 132
 	if(err)
131 133
 	    break;
132 134
     }
135
+
136
+	// load SIPEventHandlers 
137
+    for(map<string,AmSIPEventHandler*>::iterator it = name2sipeh.begin();
138
+	it != name2sipeh.end(); it++){
139
+	err = it->second->onLoad();
140
+	if(err)
141
+	    break;
142
+	// register for receiving replys 
143
+	AmReplyHandler::get()->registerReplyHandler(it->second);
144
+    }
145
+
133 146
     
134 147
     map<string,AmSessionFactory*> apps(name2app);
135 148
     for(map<string,AmSessionFactory*>::iterator it = apps.begin();
... ...
@@ -275,6 +288,14 @@ AmDynInvokeFactory* AmPlugIn::getFactory4Di(const string& name)
275 288
   return 0;
276 289
 }
277 290
 
291
+AmSIPEventHandler* AmPlugIn::getFactory4SIPeh(const string& name)
292
+{
293
+  map<string,AmSIPEventHandler*>::iterator it = name2sipeh.find(name);
294
+  if(it != name2sipeh.end())
295
+    return it->second;
296
+  return 0;
297
+}
298
+
278 299
 int AmPlugIn::loadAudioPlugIn(amci_exports_t* exports)
279 300
 {
280 301
     if(!exports){
... ...
@@ -376,6 +397,28 @@ int AmPlugIn::loadDiPlugIn(AmPluginFactory* f)
376 397
     return -1;
377 398
 }
378 399
 
400
+int AmPlugIn::loadSIPehPlugIn(AmPluginFactory* f)
401
+{
402
+    AmSIPEventHandler* sf = dynamic_cast<AmSIPEventHandler*>(f);
403
+    if(!sf){
404
+        ERROR("invalid SIP event handler plug-in!\n");
405
+        goto error;
406
+    }
407
+
408
+    if(name2sipeh.find(sf->getName()) != name2sipeh.end()){
409
+        ERROR("sip event handler component '%s' already loaded !\n",
410
+			  sf->getName().c_str());
411
+        goto error;
412
+    }
413
+      
414
+    name2sipeh.insert(std::make_pair(sf->getName(),sf));
415
+    DBG("sip event handler component '%s' loaded.\n",sf->getName().c_str());
416
+
417
+    return 0;
418
+
419
+ error:
420
+    return -1;
421
+}
379 422
 
380 423
 int AmPlugIn::addCodec(amci_codec_t* c)
381 424
 {
... ...
@@ -2,6 +2,7 @@
2 2
  * $Id$
3 3
  *
4 4
  * Copyright (C) 2002-2003 Fhg Fokus
5
+ * Copyright (C) 2006 iptego GmbH
5 6
  *
6 7
  * This file is part of sems, a free SIP media server.
7 8
  *
... ...
@@ -39,6 +40,7 @@ class AmPluginFactory;
39 40
 class AmSessionFactory;
40 41
 class AmSessionEventHandlerFactory;
41 42
 class AmDynInvokeFactory;
43
+class AmSIPEventHandler;
42 44
 
43 45
 struct amci_exports_t;
44 46
 struct amci_codec_t;
... ...
@@ -69,6 +71,7 @@ private:
69 71
 
70 72
     map<string,AmSessionEventHandlerFactory*> name2seh;
71 73
     map<string,AmDynInvokeFactory*> name2di;
74
+    map<string,AmSIPEventHandler*> name2sipeh;
72 75
 
73 76
     int dynamic_pl; // range: 96->127, see RFC 1890
74 77
     
... ...
@@ -81,6 +84,7 @@ private:
81 84
     int loadAppPlugIn(AmPluginFactory* cb);
82 85
     int loadSehPlugIn(AmPluginFactory* cb);
83 86
     int loadDiPlugIn(AmPluginFactory* cb);
87
+	int loadSIPehPlugIn(AmPluginFactory* f);
84 88
 
85 89
     int addCodec(amci_codec_t* c);
86 90
     int addPayload(amci_payload_t* p);
... ...
@@ -144,13 +148,15 @@ private:
144 148
      */
145 149
     AmDynInvokeFactory* getFactory4Di(const string& name);
146 150
 
151
+    /**
152
+     * SIP event handler lookup function
153
+     * @param name application name
154
+     * @return NULL if failed (-> handler not found).
155
+     */
156
+    AmSIPEventHandler* getFactory4SIPeh(const string& name);
157
+
147 158
     /** @return true if this record has been inserted. */
148 159
     bool registerFactory4App(const string& app_name, AmSessionFactory* f);
149 160
 };
150 161
 
151 162
 #endif
152
-
153
-// Local Variables:
154
-// mode:C++
155
-// End:
156
-
... ...
@@ -1,3 +1,31 @@
1
+/*
2
+ * $Id$
3
+ *
4
+ * Copyright (C) 2002-2003 Fhg Fokus
5
+ * Copyright (C) 2006 iptego GmbH
6
+ *
7
+ * This file is part of sems, a free SIP media server.
8
+ *
9
+ * sems is free software; you can redistribute it and/or modify
10
+ * it under the terms of the GNU General Public License as published by
11
+ * the Free Software Foundation; either version 2 of the License, or
12
+ * (at your option) any later version
13
+ *
14
+ * For a license to use the ser software under conditions
15
+ * other than those described here, or to purchase support for this
16
+ * software, please contact iptel.org by e-mail at the following addresses:
17
+ *    info@iptel.org
18
+ *
19
+ * sems is distributed in the hope that it will be useful,
20
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
+ * GNU General Public License for more details.
23
+ *
24
+ * You should have received a copy of the GNU General Public License 
25
+ * along with this program; if not, write to the Free Software 
26
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27
+ */
28
+
1 29
 #include "AmSessionContainer.h"
2 30
 #include "AmPlugIn.h"
3 31
 #include "AmApi.h"
... ...
@@ -264,19 +292,24 @@ bool AmSessionContainer::postEvent(const string& local_tag,
264 292
 				   AmEvent* event) 
265 293
 {
266 294
 //     DBG("postEvent: local_tag = %s\n",local_tag.c_str());
267
-
268 295
     as_mut.lock();
269 296
     AmSession* s = getSession(local_tag);
270 297
     as_mut.unlock();
271
-    
272
-    if(!s){
298
+
299
+	if (s  != NULL) {
300
+		s->postEvent(event);
301
+		return true;
302
+	}    
303
+	
304
+	// try session factories
305
+	AmSessionFactory* sf = AmPlugIn::instance()->getFactory4App(local_tag);
306
+	if (sf != NULL) {
307
+		sf->postEvent(event);
308
+		return true;
309
+	}
310
+
273 311
 	delete event;
274 312
 	return false;
275
-    }
276
-    
277
-//     DBG("posting...\n");
278
-    s->postEvent(event);
279
-    return true;
280 313
 }
281 314
 
282 315
 AmSession* AmSessionContainer::createSession(AmSipRequest& req)