Browse code

- moved the "dialog-lookup-container" away from the session container into AmEventDispatcher. - removed AmSIPEventHandler (its functionalities are now in AmEventDispatcher). - added possibility for each plug-in to receive out-of-dialog messages (any kind). - added possibility to handle dialogs without creating a session (=AmSession).

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

Raphael Coeffic authored on 04/06/2008 10:56:01
Showing 19 changed files
... ...
@@ -29,6 +29,7 @@
29 29
 #include "AmUtils.h"
30 30
 #include "AmPlugIn.h"
31 31
 #include "AmSessionContainer.h"
32
+#include "AmEventDispatcher.h"
32 33
 
33 34
 #define MOD_NAME "registrar_client"
34 35
 
... ...
@@ -36,8 +37,18 @@
36 37
 
37 38
 #include <unistd.h>
38 39
 
39
-EXPORT_SIP_EVENT_HANDLER_FACTORY(SIPRegistrarClient, MOD_NAME);
40
-EXPORT_PLUGIN_CLASS_FACTORY(SIPRegistrarClient, MOD_NAME);
40
+//EXPORT_SIP_EVENT_HANDLER_FACTORY(SIPRegistrarClient, MOD_NAME);
41
+//EXPORT_PLUGIN_CLASS_FACTORY(SIPRegistrarClient, MOD_NAME);
42
+
43
+extern "C" void* plugin_class_create()
44
+{
45
+    SIPRegistrarClient* reg_c = SIPRegistrarClient::instance();
46
+    assert(dynamic_cast<AmDynInvokeFactory*>(reg_c));
47
+
48
+    DBG("Hallo, alles in ordnung!\n");
49
+
50
+    return (AmPluginFactory*)reg_c;
51
+}
41 52
 
42 53
 
43 54
 SIPRegistration::SIPRegistration(const string& handle,
... ...
@@ -179,12 +190,12 @@ SIPRegistrarClient* SIPRegistrarClient::instance()
179 190
   if(_instance == NULL){
180 191
     _instance = new SIPRegistrarClient(MOD_NAME);
181 192
   }
193
+
182 194
   return _instance;
183 195
 }
184 196
 
185 197
 SIPRegistrarClient::SIPRegistrarClient(const string& name)
186
-  : AmSIPEventHandler(name),
187
-    AmEventQueue(this) ,
198
+  : AmEventQueue(this),
188 199
     uac_auth_i(NULL),
189 200
     AmDynInvokeFactory(MOD_NAME)
190 201
 { 
... ...
@@ -515,6 +526,9 @@ remove_reg_unsafe(const string& reg_id) {
515 526
     reg = it->second;
516 527
     registrations.erase(it);
517 528
   }
529
+
530
+  AmEventDispatcher::instance()->delEventQueue(reg_id);
531
+
518 532
   return reg;
519 533
 }
520 534
 
... ...
@@ -531,6 +545,8 @@ add_reg(const string& reg_id, SIPRegistration* new_reg)
531 545
 		
532 546
   }
533 547
   registrations[reg_id] = new_reg;
548
+
549
+  AmEventDispatcher::instance()->addEventQueue(reg_id,this);
534 550
   reg_mut.unlock();
535 551
 
536 552
   if (reg != NULL)
... ...
@@ -142,8 +142,7 @@ class SIPRegistration : public AmSipDialogEventHandler,
142 142
 class SIPNewRegistrationEvent;
143 143
 class SIPRemoveRegistrationEvent;
144 144
 
145
-class SIPRegistrarClient  : public AmSIPEventHandler,
146
-			    public AmThread,
145
+class SIPRegistrarClient  : public AmThread,
147 146
 			    public AmEventQueue,
148 147
 			    public AmEventHandler,
149 148
 			    public AmDynInvoke,
... ...
@@ -351,7 +351,7 @@ void WebConferenceFactory::invoke(const string& method,
351 351
 string WebConferenceFactory::getServerInfoString() {
352 352
   string res = "Server: " 
353 353
     DEFAULT_SIGNATURE  " calls: " + 
354
-    int2str(AmSessionContainer::instance()->getSize())+
354
+      int2str(AmSession::getSessionNum())+
355 355
     " active";
356 356
 
357 357
   if (stats != NULL) {
... ...
@@ -74,11 +74,20 @@ void AmSessionFactory::configureSession(AmSession* sess) {
74 74
   //SessionTimer::sess->configureSessionTimer(mod_conf);
75 75
 }
76 76
 
77
-void AmSessionFactory::postEvent(AmEvent* ev) {
78
-  ERROR("unhandled Event in %s module\n", getName().c_str());
79
-  delete ev;
77
+void AmSessionFactory::onOoDRequest(const AmSipRequest& req)
78
+{
79
+    ERROR("sorry, we don't support beginning a new session with "
80
+	  "a '%s' message\n", req.method.c_str());
81
+    
82
+    AmSipDialog::reply_error(req,501,"Not Implemented");
83
+    return;
80 84
 }
81 85
 
86
+// void AmSessionFactory::postEvent(AmEvent* ev) {
87
+//   ERROR("unhandled Event in %s module\n", getName().c_str());
88
+//   delete ev;
89
+// }
90
+
82 91
 AmSessionEventHandlerFactory::AmSessionEventHandlerFactory(const string& name)
83 92
   : AmPluginFactory(name) 
84 93
 {
... ...
@@ -90,10 +99,10 @@ bool AmSessionEventHandlerFactory::onInvite(const AmSipRequest& req,
90 99
   return onInvite(req);
91 100
 }
92 101
 
93
-AmSIPEventHandler::AmSIPEventHandler(const string& name) 
94
-  : AmPluginFactory(name) 
95
-{
96
-}
102
+// AmSIPEventHandler::AmSIPEventHandler(const string& name) 
103
+//   : AmPluginFactory(name) 
104
+// {
105
+// }
97 106
 
98 107
 AmLoggingFacility::AmLoggingFacility(const string& name) 
99 108
   : AmPluginFactory(name) 
... ...
@@ -182,38 +182,37 @@ class AmSessionFactory: public AmPluginFactory
182 182
 			     AmArg& session_params);
183 183
 
184 184
   /**
185
-   * method to receive an Event that is posted
186
-   * to  the factory
185
+   * Method to receive any out-of-dialog request 
186
+   * other than INVITE, REFER and OPTIONS
187 187
    *
188 188
    * Warning:
189 189
    *   This method should not make any expensive
190 190
    *   processing as it would block the thread 
191 191
    *   posting the event!
192 192
    */
193
-  virtual void postEvent(AmEvent* ev);	
194
-
193
+  virtual void onOoDRequest(const AmSipRequest& req);
195 194
 };
196 195
 
197 196
 /** \brief Interface for plugins that implement session-less 
198 197
  *     UA behaviour (e.g. registrar client, event notification 
199 198
  *     client)
200 199
  */
201
-class AmSIPEventHandler : public AmPluginFactory 
202
-{
203
-
204
- public:
205
-  AmSIPEventHandler(const string& name);
206
-  virtual ~AmSIPEventHandler() { }
207
-
208
-  /** will be called on incoming replies which do 
209
-   *  not belong to a dialog of a session in the 
210
-   *  SessionContainer.
211
-   *
212
-   *  @return true if reply was handled by plugin, false 
213
-   *          otherwise
214
-   */
215
-  virtual bool onSipReply(const AmSipReply& rep) = 0;
216
-};
200
+// class AmSIPEventHandler : public AmPluginFactory 
201
+// {
202
+
203
+//  public:
204
+//   AmSIPEventHandler(const string& name);
205
+//   virtual ~AmSIPEventHandler() { }
206
+
207
+//   /** will be called on incoming replies which do 
208
+//    *  not belong to a dialog of a session in the 
209
+//    *  SessionContainer.
210
+//    *
211
+//    *  @return true if reply was handled by plugin, false 
212
+//    *          otherwise
213
+//    */
214
+//   virtual bool onSipReply(const AmSipReply& rep) = 0;
215
+// };
217 216
 
218 217
 /** \brief Interface for plugins that implement a
219 218
  *     logging facility
... ...
@@ -230,8 +229,6 @@ class AmLoggingFacility : public AmPluginFactory
230 229
   virtual void log(int level, const char* msg) = 0;
231 230
 };
232 231
 
233
-class AmInterfaceHandler;
234
-
235 232
 class AmCtrlInterface: public AmThread
236 233
 {
237 234
  public:
... ...
@@ -260,10 +257,9 @@ class AmCtrlInterface: public AmThread
260 257
  * For sending messages, appropriate methods are exposed (the send()s).
261 258
  * The interface defines a thread that runs, polling on the two listening unix
262 259
  * sockets (one for requests, one for replies). After receiving a message,
263
- * a registered 'AmInterfaceHandler' is used to handle the incomming SIP
264
- * events (that end up either opening/updating a UAC session or posting to a
265
- * SIP event queue).
266
- *
260
+ * AmSipDispatcher shall be used to dispatch the incomming SIP messages 
261
+ * (that end up either opening/updating a UAC session or posting to some
262
+ * event queue).
267 263
  */
268 264
 class AmCtrlInterfaceFactory : public AmPluginFactory
269 265
 {
270 266
new file mode 100644
... ...
@@ -0,0 +1,147 @@
1
+/*
2
+ * $Id: $
3
+ *
4
+ * Copyright (C) 2007 Raphael Coeffic
5
+ *
6
+ * This file is part of sems, a free SIP media server.
7
+ *
8
+ * sems is free software; you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation; either version 2 of the License, or
11
+ * (at your option) any later version
12
+ *
13
+ * For a license to use the ser software under conditions
14
+ * other than those described here, or to purchase support for this
15
+ * software, please contact iptel.org by e-mail at the following addresses:
16
+ *    info@iptel.org
17
+ *
18
+ * sems is distributed in the hope that it will be useful,
19
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
+ * GNU General Public License for more details.
22
+ *
23
+ * You should have received a copy of the GNU General Public License 
24
+ * along with this program; if not, write to the Free Software 
25
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26
+ */
27
+
28
+#include "AmEventDispatcher.h"
29
+#include "AmSipEvent.h"
30
+
31
+AmEventDispatcher* AmEventDispatcher::_instance=NULL;
32
+
33
+AmEventDispatcher* AmEventDispatcher::instance()
34
+{
35
+  return _instance ? _instance : ((_instance = new AmEventDispatcher()));
36
+}
37
+
38
+bool AmEventDispatcher::addEventQueue(const string& local_tag, 
39
+				      AmEventQueue* q,
40
+				      const string& callid, 
41
+				      const string& remote_tag)
42
+{
43
+    bool exists = false;
44
+
45
+    m_queues.lock();
46
+
47
+    exists = queues.find(local_tag) != queues.end();
48
+
49
+    if(!callid.empty() && !remote_tag.empty()) {
50
+	exists = exists ||
51
+	    (id_lookup.find(callid+remote_tag) != id_lookup.end());
52
+    }
53
+
54
+    if(!exists){
55
+	queues[local_tag] = q;
56
+
57
+	if(!callid.empty() && !remote_tag.empty())
58
+	    id_lookup[callid+remote_tag] = local_tag;
59
+    }
60
+
61
+    m_queues.unlock();
62
+    
63
+    return exists;
64
+}
65
+
66
+AmEventQueue* AmEventDispatcher::delEventQueue(const string& local_tag,
67
+					       const string& callid, 
68
+					       const string& remote_tag)
69
+{
70
+    AmEventQueue* q = NULL;
71
+    
72
+    m_queues.lock();
73
+    
74
+    EvQueueMapIter qi = queues.find(local_tag);
75
+    if(qi != queues.end()) {
76
+
77
+	q = qi->second;
78
+	queues.erase(qi);
79
+
80
+	if(!callid.empty() && !remote_tag.empty()) {
81
+
82
+	    DictIter di = id_lookup.find(callid+remote_tag);
83
+	    if(di != id_lookup.end()) {
84
+		
85
+		id_lookup.erase(di);
86
+	    }
87
+	}
88
+    }
89
+    m_queues.unlock();
90
+    
91
+    return q;
92
+}
93
+
94
+bool AmEventDispatcher::post(const string& local_tag, AmEvent* ev)
95
+{
96
+    bool posted = false;
97
+    m_queues.lock();
98
+
99
+    EvQueueMapIter it = queues.find(local_tag);
100
+    if(it != queues.end()){
101
+	it->second->postEvent(ev);
102
+	posted = true;
103
+    }
104
+
105
+    m_queues.unlock();
106
+    
107
+    return posted;
108
+}
109
+
110
+bool AmEventDispatcher::post(const string& callid, const string& remote_tag, AmEvent* ev)
111
+{
112
+    bool posted = false;
113
+    m_queues.lock();
114
+
115
+    DictIter di = id_lookup.find(callid+remote_tag);
116
+    if(di != id_lookup.end()) {
117
+
118
+	EvQueueMapIter it = queues.find(di->second);
119
+	if(it != queues.end()){
120
+	    it->second->postEvent(ev);
121
+	    posted = true;
122
+	}
123
+    }
124
+    m_queues.unlock();
125
+    
126
+    return posted;
127
+}
128
+
129
+bool AmEventDispatcher::postSipRequest(const string& callid, const string& remote_tag, 
130
+				       const AmSipRequest& req)
131
+{
132
+    bool posted = false;
133
+    m_queues.lock();
134
+
135
+    DictIter di = id_lookup.find(callid+remote_tag);
136
+    if(di != id_lookup.end()) {
137
+
138
+	EvQueueMapIter it = queues.find(di->second);
139
+	if(it != queues.end()){
140
+	  it->second->postEvent(new AmSipRequestEvent(req));
141
+	    posted = true;
142
+	}
143
+    }
144
+    m_queues.unlock();
145
+    
146
+    return posted;
147
+}
0 148
new file mode 100644
... ...
@@ -0,0 +1,85 @@
1
+/*
2
+ * $Id: $
3
+ *
4
+ * Copyright (C) 2008 Raphael Coeffic
5
+ *
6
+ * This file is part of sems, a free SIP media server.
7
+ *
8
+ * sems is free software; you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation; either version 2 of the License, or
11
+ * (at your option) any later version
12
+ *
13
+ * For a license to use the ser software under conditions
14
+ * other than those described here, or to purchase support for this
15
+ * software, please contact iptel.org by e-mail at the following addresses:
16
+ *    info@iptel.org
17
+ *
18
+ * sems is distributed in the hope that it will be useful,
19
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
+ * GNU General Public License for more details.
22
+ *
23
+ * You should have received a copy of the GNU General Public License 
24
+ * along with this program; if not, write to the Free Software 
25
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26
+ */
27
+#ifndef _AMEVENTDISPATCHER_h_ 
28
+#define _AMEVENTDISPATCHER_h_
29
+
30
+#include "AmEventQueue.h"
31
+#include "AmSipMsg.h"
32
+#include <map>
33
+
34
+class AmEventDispatcher
35
+{
36
+public:
37
+
38
+    typedef std::map<string, AmEventQueue*> EvQueueMap;
39
+    typedef EvQueueMap::iterator            EvQueueMapIter;
40
+    
41
+    typedef std::map<string,string>  Dictionnary;
42
+    typedef Dictionnary::iterator    DictIter;
43
+
44
+
45
+private:
46
+
47
+    static AmEventDispatcher *_instance;
48
+
49
+    /** 
50
+     * Container for active sessions 
51
+     * local tag -> event queue
52
+     */
53
+    EvQueueMap queues;
54
+
55
+    /** 
56
+     * Call ID + remote tag -> local tag 
57
+     *  (needed for CANCELs and some provisionnal answers)
58
+     *  (UAS sessions only)
59
+     */
60
+    Dictionnary id_lookup;
61
+    
62
+    // mutex for "queues" and "id_lookup"
63
+    AmMutex m_queues;
64
+
65
+public:
66
+
67
+    static AmEventDispatcher* instance();
68
+
69
+    bool postSipRequest(const string& callid, const string& remote_tag, 
70
+			const AmSipRequest& req);
71
+
72
+    bool post(const string& local_tag, AmEvent* ev);
73
+    bool post(const string& callid, const string& remote_tag, AmEvent* ev);
74
+
75
+    bool addEventQueue(const string& local_tag, 
76
+		       AmEventQueue* q,
77
+		       const string& callid="", 
78
+		       const string& remote_tag="");
79
+
80
+    AmEventQueue* delEventQueue(const string& local_tag,
81
+				const string& callid="", 
82
+				const string& remote_tag="");
83
+};
84
+
85
+#endif
... ...
@@ -51,7 +51,7 @@ protected:
51 51
 
52 52
 public:
53 53
   AmEventQueue(AmEventHandler*);
54
-  ~AmEventQueue();
54
+  virtual ~AmEventQueue();
55 55
 
56 56
   void postEvent(AmEvent*);
57 57
   void processEvents();
... ...
@@ -227,15 +227,15 @@ int AmPlugIn::load(const string& directory, const string& plugins)
227 227
   }
228 228
 
229 229
   // load SIPEventHandlers 
230
-  for(std::map<std::string,AmSIPEventHandler*>::iterator it = name2sipeh.begin();
231
-      it != name2sipeh.end(); it++){
232
-    err = it->second->onLoad();
233
-    if(err)
234
-      return err;
235
-    // register for receiving replys 
236
-    //AmReplyHandler::get()->registerReplyHandler(it->second);
237
-    AmSipDispatcher::instance()->registerReplyHandler(it->second);
238
-  }
230
+//   for(std::map<std::string,AmSIPEventHandler*>::iterator it = name2sipeh.begin();
231
+//       it != name2sipeh.end(); it++){
232
+//     err = it->second->onLoad();
233
+//     if(err)
234
+//       return err;
235
+//     // register for receiving replys 
236
+//     //AmReplyHandler::get()->registerReplyHandler(it->second);
237
+//     AmSipDispatcher::instance()->registerReplyHandler(it->second);
238
+//   }
239 239
 
240 240
   // init logging facilities
241 241
   for(std::map<std::string,AmLoggingFacility*>::iterator it = name2logfac.begin();
... ...
@@ -311,11 +311,11 @@ int AmPlugIn::loadPlugIn(const string& file)
311 311
     has_sym=true;
312 312
   }
313 313
 
314
-  if((fc = (FactoryCreate)dlsym(h_dl,FACTORY_SIP_EVENT_HANDLER_EXPORT_STR)) != NULL){
315
-    if(loadSIPehPlugIn((AmPluginFactory*)fc()))
316
-      goto error;
317
-    has_sym=true;
318
-  }
314
+//   if((fc = (FactoryCreate)dlsym(h_dl,FACTORY_SIP_EVENT_HANDLER_EXPORT_STR)) != NULL){
315
+//     if(loadSIPehPlugIn((AmPluginFactory*)fc()))
316
+//       goto error;
317
+//     has_sym=true;
318
+//   }
319 319
 
320 320
   if((fc = (FactoryCreate)dlsym(h_dl,FACTORY_LOG_FACILITY_EXPORT_STR)) != NULL){
321 321
     if(loadLogFacPlugIn((AmPluginFactory*)fc()))
... ...
@@ -444,13 +444,13 @@ AmDynInvokeFactory* AmPlugIn::getFactory4Di(const string& name)
444 444
   return 0;
445 445
 }
446 446
 
447
-AmSIPEventHandler* AmPlugIn::getFactory4SIPeh(const string& name)
448
-{
449
-  std::map<std::string,AmSIPEventHandler*>::iterator it = name2sipeh.find(name);
450
-  if(it != name2sipeh.end())
451
-    return it->second;
452
-  return 0;
453
-}
447
+// AmSIPEventHandler* AmPlugIn::getFactory4SIPeh(const string& name)
448
+// {
449
+//   std::map<std::string,AmSIPEventHandler*>::iterator it = name2sipeh.find(name);
450
+//   if(it != name2sipeh.end())
451
+//     return it->second;
452
+//   return 0;
453
+// }
454 454
 
455 455
 AmLoggingFacility* AmPlugIn::getFactory4LogFaclty(const string& name)
456 456
 {
... ...
@@ -574,28 +574,28 @@ int AmPlugIn::loadDiPlugIn(AmPluginFactory* f)
574 574
   return -1;
575 575
 }
576 576
 
577
-int AmPlugIn::loadSIPehPlugIn(AmPluginFactory* f)
578
-{
579
-  AmSIPEventHandler* sf = dynamic_cast<AmSIPEventHandler*>(f);
580
-  if(!sf){
581
-    ERROR("invalid SIP event handler plug-in!\n");
582
-    goto error;
583
-  }
577
+// int AmPlugIn::loadSIPehPlugIn(AmPluginFactory* f)
578
+// {
579
+//   AmSIPEventHandler* sf = dynamic_cast<AmSIPEventHandler*>(f);
580
+//   if(!sf){
581
+//     ERROR("invalid SIP event handler plug-in!\n");
582
+//     goto error;
583
+//   }
584 584
 
585
-  if(name2sipeh.find(sf->getName()) != name2sipeh.end()){
586
-    ERROR("sip event handler component '%s' already loaded !\n",
587
-	  sf->getName().c_str());
588
-    goto error;
589
-  }
585
+//   if(name2sipeh.find(sf->getName()) != name2sipeh.end()){
586
+//     ERROR("sip event handler component '%s' already loaded !\n",
587
+// 	  sf->getName().c_str());
588
+//     goto error;
589
+//   }
590 590
       
591
-  name2sipeh.insert(std::make_pair(sf->getName(),sf));
592
-  DBG("sip event handler component '%s' loaded.\n",sf->getName().c_str());
591
+//   name2sipeh.insert(std::make_pair(sf->getName(),sf));
592
+//   DBG("sip event handler component '%s' loaded.\n",sf->getName().c_str());
593 593
 
594
-  return 0;
594
+//   return 0;
595 595
 
596
- error:
597
-  return -1;
598
-}
596
+//  error:
597
+//   return -1;
598
+// }
599 599
 
600 600
 int AmPlugIn::loadLogFacPlugIn(AmPluginFactory* f)
601 601
 {
... ...
@@ -745,3 +745,55 @@ bool AmPlugIn::registerFactory4App(const string& app_name, AmSessionFactory* f)
745 745
   name2app.insert(make_pair(app_name,f));
746 746
   return true;
747 747
 }
748
+
749
+AmSessionFactory* AmPlugIn::findSessionFactory(AmSipRequest& req)
750
+{
751
+  if(req.cmd.empty()){
752
+    ERROR("AmPlugIn::findSessionFactory: req.cmd is empty!\n");
753
+    return NULL;
754
+  } 
755
+  else if(req.cmd == "sems"){
756
+
757
+    switch (AmConfig::AppSelect) {
758
+
759
+    case AmConfig::App_RURIUSER:
760
+      req.cmd = req.user; 
761
+      break;
762
+    case AmConfig::App_APPHDR: 
763
+      req.cmd = getHeader(req.hdrs, APPNAME_HDR); 
764
+      break;      
765
+    case AmConfig::App_RURIPARAM: 
766
+      req.cmd = get_header_param(req.r_uri, "app");
767
+      break;
768
+    case AmConfig::App_MAPPING: 
769
+      {
770
+	req.cmd = "";	
771
+	for (AmConfig::AppMappingVector::iterator it = 
772
+	       AmConfig::AppMapping.begin(); 
773
+	     it != AmConfig::AppMapping.end(); it++){
774
+	  if (!regexec(&it->first, req.r_uri.c_str(), 0, NULL, 0)) {
775
+	    DBG("match of r_uri '%s' to application %s\n", 
776
+	      req.r_uri.c_str(), it->second.c_str());
777
+	    req.cmd = it->second;
778
+	    break;
779
+	  }
780
+	}
781
+      } break;
782
+    case AmConfig::App_SPECIFIED: 
783
+      req.cmd = AmConfig::Application; 
784
+      break;
785
+    }
786
+
787
+    if (req.cmd.empty()) {
788
+	ERROR("could not find any application matching configured criteria\n");
789
+	return NULL;
790
+    }
791
+  }
792
+
793
+  AmSessionFactory* session_factory = getFactory4App(req.cmd);
794
+  if(!session_factory) {
795
+    ERROR("AmPlugIn::findSessionFactory: application '%s' not found !\n", req.cmd.c_str());
796
+  }
797
+
798
+  return session_factory;
799
+}
... ...
@@ -40,9 +40,10 @@ class AmPluginFactory;
40 40
 class AmSessionFactory;
41 41
 class AmSessionEventHandlerFactory;
42 42
 class AmDynInvokeFactory;
43
-class AmSIPEventHandler;
43
+//class AmSIPEventHandler;
44 44
 class AmLoggingFacility;
45 45
 class AmCtrlInterfaceFactory;
46
+class AmSipRequest;
46 47
 
47 48
 struct amci_exports_t;
48 49
 struct amci_codec_t;
... ...
@@ -91,13 +92,13 @@ class AmPlugIn : public AmPayloadProviderInterface
91 92
   std::map<int,amci_payload_t*>     payloads;
92 93
   std::map<int,int>                 payload_order;
93 94
   std::map<string,amci_inoutfmt_t*> file_formats;
94
-  std::map<string,AmSessionFactory*>  name2app;
95 95
 
96
+  std::map<string,AmSessionFactory*>             name2app;
96 97
   std::map<string,AmSessionEventHandlerFactory*> name2seh;
97
-  std::map<string,AmPluginFactory*> name2base;
98
-  std::map<string,AmDynInvokeFactory*> name2di;
99
-  std::map<string,AmSIPEventHandler*> name2sipeh;
100
-  std::map<string,AmLoggingFacility*> name2logfac;
98
+  std::map<string,AmPluginFactory*>              name2base;
99
+  std::map<string,AmDynInvokeFactory*>           name2di;
100
+  std::map<string,AmLoggingFacility*>            name2logfac;
101
+
101 102
   AmCtrlInterfaceFactory *ctrlIface;
102 103
 
103 104
   int dynamic_pl; // range: 96->127, see RFC 1890
... ...
@@ -114,7 +115,6 @@ class AmPlugIn : public AmPayloadProviderInterface
114 115
   int loadSehPlugIn(AmPluginFactory* cb);
115 116
   int loadBasePlugIn(AmPluginFactory* cb);
116 117
   int loadDiPlugIn(AmPluginFactory* cb);
117
-  int loadSIPehPlugIn(AmPluginFactory* f);
118 118
   int loadLogFacPlugIn(AmPluginFactory* f);
119 119
   int loadCtrlFacPlugIn(AmPluginFactory* f);
120 120
 
... ...
@@ -150,8 +150,10 @@ class AmPlugIn : public AmPayloadProviderInterface
150 150
 
151 151
   /** @return the suported payloads. */
152 152
   const std::map<int,amci_payload_t*>& getPayloads() { return payloads; }
153
+
153 154
   /** @return the order of payloads. */
154 155
   const std::map<int,int>& getPayloadOrder() { return payload_order; }
156
+
155 157
   /** 
156 158
    * File format lookup according to the 
157 159
    * format name and/or file extension.
... ...
@@ -160,6 +162,7 @@ class AmPlugIn : public AmPayloadProviderInterface
160 162
    * @return NULL if failed.
161 163
    */
162 164
   amci_inoutfmt_t* fileFormat(const string& fmt_name, const string& ext = "");
165
+
163 166
   /** 
164 167
    * File format's subtype lookup function.
165 168
    * @param iofmt The file format.
... ...
@@ -167,12 +170,14 @@ class AmPlugIn : public AmPayloadProviderInterface
167 170
    * @return NULL if failed.
168 171
    */
169 172
   amci_subtype_t*  subtype(amci_inoutfmt_t* iofmt, int subtype);
173
+
170 174
   /** 
171 175
    * Codec lookup function.
172 176
    * @param id Codec ID (see amci/codecs.h).
173 177
    * @return NULL if failed.
174 178
    */
175 179
   amci_codec_t*    codec(int id);
180
+
176 181
   /**
177 182
    * Application lookup function
178 183
    * @param app_name application name
... ...
@@ -180,6 +185,15 @@ class AmPlugIn : public AmPayloadProviderInterface
180 185
    */
181 186
   AmSessionFactory* getFactory4App(const string& app_name);
182 187
 
188
+  /** @return true if this record has been inserted. */
189
+  bool registerFactory4App(const string& app_name, AmSessionFactory* f);
190
+
191
+  /**
192
+   * Find the proper SessionFactory
193
+   * for the given request.
194
+   */
195
+  AmSessionFactory* findSessionFactory(AmSipRequest& req);
196
+
183 197
   /**
184 198
    * Session event handler lookup function
185 199
    * @param name application name
... ...
@@ -192,13 +206,6 @@ class AmPlugIn : public AmPayloadProviderInterface
192 206
    */
193 207
   AmDynInvokeFactory* getFactory4Di(const string& name);
194 208
 
195
-  /**
196
-   * SIP event handler lookup function
197
-   * @param name application name
198
-   * @return NULL if failed (-> handler not found).
199
-   */
200
-  AmSIPEventHandler* getFactory4SIPeh(const string& name);
201
-
202 209
   /**
203 210
    * logging facility lookup function
204 211
    * @param name application name
... ...
@@ -206,8 +213,6 @@ class AmPlugIn : public AmPayloadProviderInterface
206 213
    */
207 214
   AmLoggingFacility* getFactory4LogFaclty(const string& name);
208 215
 
209
-  /** @return true if this record has been inserted. */
210
-  bool registerFactory4App(const string& app_name, AmSessionFactory* f);
211 216
 };
212 217
 
213 218
 #endif
... ...
@@ -49,6 +49,9 @@
49 49
 #include <assert.h>
50 50
 #include <sys/time.h>
51 51
 
52
+volatile unsigned int AmSession::session_num = 0;
53
+
54
+
52 55
 // AmSessionEventHandler methods
53 56
 bool AmSessionEventHandler::process(AmEvent*)
54 57
 {
... ...
@@ -387,6 +390,8 @@ void AmSession::run()
387 390
   }
388 391
 #endif
389 392
 
393
+  session_num++;
394
+
390 395
   try {
391 396
     try {
392 397
 
... ...
@@ -430,8 +435,10 @@ void AmSession::run()
430 435
   catch(const AmSession::Exception& e){
431 436
     ERROR("%i %s\n",e.code,e.reason.c_str());
432 437
   }
433
-	
438
+
434 439
   destroy();
440
+
441
+  session_num--;
435 442
     
436 443
   // wait at least until session is out of RtpScheduler
437 444
   DBG("session is stopped.\n");
... ...
@@ -469,6 +476,12 @@ string AmSession::getNewId()
469 476
   return id;
470 477
 }
471 478
 
479
+unsigned int AmSession::getSessionNum()
480
+{
481
+    return AmSession::session_num;
482
+}
483
+
484
+
472 485
 void AmSession::setInbandDetector(Dtmf::InbandDetectorType t)
473 486
 { 
474 487
   m_dtmfDetector.setInbandDetector(t); 
... ...
@@ -58,7 +58,8 @@ class AmDtmfEvent;
58 58
 #define FL_FORCE_ACTIVE 2
59 59
 
60 60
 /**
61
- * \brief Interface for SIP events signaling plugins implement
61
+ * \brief Interface for SIP signaling plugins that
62
+ *        must change requests or replies (ex: session timer).
62 63
  *
63 64
  *  Signaling plugins must inherite from this class.
64 65
  */
... ...
@@ -73,8 +74,8 @@ public:
73 74
 
74 75
   virtual ~AmSessionEventHandler() {}
75 76
   /* 
76
-   * All the methods return true if event processing 
77
-   * should stopped after calling them.
77
+   * All the methods return true if the event processing 
78
+   * shall be stopped after them.
78 79
    */
79 80
   virtual bool process(AmEvent*);
80 81
   virtual bool onSipEvent(AmSipEvent*);
... ...
@@ -142,6 +143,8 @@ private:
142 143
   AmCondition<bool> sess_stopped;
143 144
   AmCondition<bool> detached;
144 145
 
146
+  static volatile unsigned int session_num;
147
+
145 148
   friend class AmMediaProcessor;
146 149
   friend class AmMediaProcessorThread;
147 150
   friend class AmSessionContainer;
... ...
@@ -364,6 +367,11 @@ public:
364 367
    */
365 368
   static string getNewId();
366 369
 
370
+    /**
371
+     * Gets the number of running sessions
372
+     */
373
+    static unsigned int getSessionNum();
374
+
367 375
   /**
368 376
    * Entry point for DTMF events
369 377
    */
... ...
@@ -31,9 +31,12 @@
31 31
 #include "AmApi.h"
32 32
 #include "AmConfig.h"
33 33
 #include "AmUtils.h"
34
+#include "AmEventDispatcher.h"
35
+
34 36
 #include <assert.h>
35 37
 #include <sys/types.h>
36 38
 #include <unistd.h>
39
+
37 40
 #include "sems.h"
38 41
 
39 42
 // AmSessionContainer methods
... ...
@@ -41,7 +44,8 @@
41 44
 AmSessionContainer* AmSessionContainer::_SessionContainer=0;
42 45
 
43 46
 AmSessionContainer::AmSessionContainer()
44
-  : _run_cond(false)
47
+    : _run_cond(false)
48
+      
45 49
 {
46 50
 }
47 51
 
... ...
@@ -136,52 +140,22 @@ void AmSessionContainer::destroySession(AmSession* s)
136 140
 
137 141
 void AmSessionContainer::destroySession(const string& local_tag)
138 142
 {
139
-  as_mut.lock();
140
-
141
-  SessionMapIter sess_it = a_sessions.find(local_tag);
142
-  if(sess_it != a_sessions.end()){
143
-	
144
-    AmSession* sess = sess_it->second;
145
-    as_id_lookup.erase(sess->getCallID() + sess->getRemoteTag());
146
-    a_sessions.erase(sess_it);
143
+    AmSession* s = NULL;
144
+    AmEventQueue* q = AmEventDispatcher::instance()->
145
+	delEventQueue(local_tag);
146
+    
147
+    if(q &&
148
+       (s = dynamic_cast<AmSession*>(q))) {
147 149
 	
148
-    stopAndQueue(sess);
149
-    DBG("session stopped and queued for deletion (#sessions=%u)\n",
150
-	(unsigned int)a_sessions.size());
151
-  }
152
-  else {
153
-    DBG("could not remove session: id not found\n");
154
-  }
155
-
156
-  as_mut.unlock();
157
-}
158
-
159
-AmSession* AmSessionContainer::getSession(const string& callid, const string& remote_tag)
160
-{
161
-  DictIter it = as_id_lookup.find(callid+remote_tag);
162
-  if(it == as_id_lookup.end()){
163
-    //ERROR("could not find session (callid='%s'; remote_tag='%s')\n",
164
-    //      callid.c_str(),remote_tag.c_str());
165
-    return NULL;
166
-  }
167
-
168
-  return getSession(it->second);
169
-}
170
-
171
-AmSession* AmSessionContainer::getSession(const string& local_tag)
172
-{
173
-  SessionMapIter it = a_sessions.find(local_tag);
174
-  if(it == a_sessions.end()){
175
-      //ERROR("could not find session (local_tag='%s')\n",local_tag.c_str());
176
-    return NULL;
177
-  }
178
-
179
-  return it->second;
150
+	stopAndQueue(s);
151
+    }
152
+    else {
153
+	DBG("could not remove session: id not found or wrong type\n");
154
+    }
180 155
 }
181 156
 
182 157
 AmSession* AmSessionContainer::startSessionUAC(AmSipRequest& req, AmArg* session_params) {
183 158
   AmSession* session = NULL;
184
-  as_mut.lock();
185 159
   try {
186 160
     if((session = createSession(req, session_params)) != 0){
187 161
       session->dlg.updateStatusFromLocalRequest(req); // sets local tag as well
... ...
@@ -192,7 +166,6 @@ AmSession* AmSessionContainer::startSessionUAC(AmSipRequest& req, AmArg* session
192 166
 	ERROR("INVITE could not be sent: error code = %d.\n", 
193 167
 	      err);
194 168
 	delete session;
195
-	as_mut.unlock();
196 169
 	return NULL;
197 170
       }
198 171
 
... ...
@@ -203,9 +176,7 @@ AmSession* AmSessionContainer::startSessionUAC(AmSipRequest& req, AmArg* session
203 176
 
204 177
       session->start();
205 178
 
206
-      addSession_unsafe(req.callid,"",req.from_tag,session);
207
-      // session does not get its own INVITE
208
-      //      session->postEvent(new AmSipRequestEvent(req)); 
179
+      addSession("","",req.from_tag,session);
209 180
     }
210 181
   } 
211 182
   catch(const AmSession::Exception& e){
... ...
@@ -220,23 +191,13 @@ AmSession* AmSessionContainer::startSessionUAC(AmSipRequest& req, AmArg* session
220 191
     ERROR("unexpected exception\n");
221 192
     AmSipDialog::reply_error(req,500,"unexpected exception");
222 193
   }
223
-  as_mut.unlock();
194
+
224 195
   return session;
225 196
 }
226 197
 
227 198
 void AmSessionContainer::startSessionUAS(AmSipRequest& req)
228 199
 {
229
-  as_mut.lock();
230 200
   try {
231
-	
232
-    AmSession* session = getSession(req.callid,req.from_tag);
233
-    if( session ){
234
-	    
235
-      // it's a forked-and-merged INVITE
236
-      // reply 482 Loop detected
237
-      throw AmSession::Exception(482, "Loop detected");
238
-    }
239
-    else {
240 201
       // Call-ID and From-Tag are unknown: it's a new session
241 202
       AmSession* session;
242 203
       if((session = createSession(req)) != 0){
... ...
@@ -254,10 +215,9 @@ void AmSessionContainer::startSessionUAS(AmSipRequest& req)
254 215
 
255 216
 	session->start();
256 217
 
257
-	addSession_unsafe(req.callid,req.from_tag,local_tag,session);
218
+	addSession(req.callid,req.from_tag,local_tag,session);
258 219
 	session->postEvent(new AmSipRequestEvent(req));
259 220
       }
260
-    }
261 221
   } 
262 222
   catch(const AmSession::Exception& e){
263 223
     ERROR("%i %s\n",e.code,e.reason.c_str());
... ...
@@ -271,7 +231,6 @@ void AmSessionContainer::startSessionUAS(AmSipRequest& req)
271 231
     ERROR("unexpected exception\n");
272 232
     AmSipDialog::reply_error(req,500,"unexpected exception");
273 233
   }
274
-  as_mut.unlock();
275 234
 }
276 235
 
277 236
 
... ...
@@ -279,186 +238,95 @@ bool AmSessionContainer::postEvent(const string& callid,
279 238
 				   const string& remote_tag,
280 239
 				   AmEvent* event)
281 240
 {
282
-  //     DBG("postEvent: callid = %s; remote_tag = %s\n",
283
-  // 	callid.c_str(),remote_tag.c_str());
241
+    bool posted =
242
+	AmEventDispatcher::instance()->
243
+	post(callid,remote_tag,event);
284 244
 
285
-  as_mut.lock();
286
-  AmSession* s = getSession(callid,remote_tag);
287
-    
288
-  if(!s){
289
-    as_mut.unlock();
290
-    delete event;
291
-    return false;
292
-  }
293
-    
294
-  s->postEvent(event);
295
-  as_mut.unlock();
245
+    if(!posted)
246
+	delete event;
296 247
 
297
-  return true;
248
+    return posted;
298 249
 }
299 250
 
300 251
 bool AmSessionContainer::postEvent(const string& local_tag,
301 252
 				   AmEvent* event) 
302 253
 {
303
-  //     DBG("postEvent: local_tag = %s\n",local_tag.c_str());
304
-  as_mut.lock();
305
-  AmSession* s = getSession(local_tag);
306
-
307
-  if (s  != NULL) {
308
-    s->postEvent(event);
309
-    as_mut.unlock();
310
-    return true;
311
-  }    
312
-  as_mut.unlock();
313
-	
314
-  // try session factories
315
-  AmSessionFactory* sf = AmPlugIn::instance()->getFactory4App(local_tag);
316
-  if (sf != NULL) {
317
-    sf->postEvent(event);
318
-    return true;
319
-  }
254
+    bool posted =
255
+	AmEventDispatcher::instance()->
256
+	post(local_tag,event);
257
+
258
+    if(!posted)
259
+	delete event;
260
+
261
+    return posted;
320 262
 
321
-  delete event;
322
-  return false;
323 263
 }
324 264
 
325 265
 AmSession* AmSessionContainer::createSession(AmSipRequest& req, 
326 266
 					     AmArg* session_params)
327 267
 {
328
-  
329
-  if (AmConfig::SessionLimit &&                   
330
-      AmConfig::SessionLimit <= a_sessions.size()) {
331
-    DBG("session_limit %d reached. Not creating session.\n", 
332
-	AmConfig::SessionLimit);
333
-    throw AmSession::Exception(AmConfig::SessionLimitErrCode, AmConfig::SessionLimitErrReason);
268
+  if (AmConfig::SessionLimit &&
269
+      AmConfig::SessionLimit <= AmSession::session_num) {
270
+      
271
+      DBG("session_limit %d reached. Not creating session.\n", 
272
+	  AmConfig::SessionLimit);
273
+
274
+      AmSipDialog::reply_error(req,AmConfig::SessionLimitErrCode, 
275
+			       AmConfig::SessionLimitErrReason);
276
+      return NULL;
334 277
   }
335 278
 
336
-  if(req.cmd.empty()){
337
-    throw string("AmSessionContainer::createSession: req.cmd is empty!\n");
338
-  } 
339
-  else if(req.cmd == "sems"){
340
-    switch (AmConfig::AppSelect) {
341
-    case AmConfig::App_RURIUSER:
342
-      req.cmd = req.user; 
343
-      break;
344
-    case AmConfig::App_APPHDR: 
345
-      req.cmd = getHeader(req.hdrs, APPNAME_HDR); 
346
-      break;      
347
-    case AmConfig::App_RURIPARAM: 
348
-      req.cmd = get_header_param(req.r_uri, "app");
349
-      break;
350
-    case AmConfig::App_MAPPING: 
351
-      {
352
-	req.cmd = "";	
353
-	for (AmConfig::AppMappingVector::iterator it = 
354
-	       AmConfig::AppMapping.begin(); 
355
-	     it != AmConfig::AppMapping.end(); it++){
356
-	  if (!regexec(&it->first, req.r_uri.c_str(), 0, NULL, 0)) {
357
-	    DBG("match of r_uri '%s' to application %s\n", 
358
-	      req.r_uri.c_str(), it->second.c_str());
359
-	    req.cmd = it->second;
360
-	    break;
361
-	  }
362
-	}
363
-      } break;
364
-    case AmConfig::App_SPECIFIED: 
365
-      req.cmd = AmConfig::Application; 
366
-      break;
367
-    }
368
-    if (req.cmd.empty()) {
369
-      string ex = "Unknown Application";
370
-      throw ex; 
371
-    }
372
-  }
279
+  AmSessionFactory* session_factory = 
280
+      AmPlugIn::instance()->findSessionFactory(req);
373 281
 
374
-  AmSessionFactory* state_factory = AmPlugIn::instance()->getFactory4App(req.cmd);
375
-  if(!state_factory) {
376
-    ERROR("application '%s' not found !\n", req.cmd.c_str());
377
-    throw string("application '" + req.cmd + "' not found !");
282
+  if(!session_factory) {
283
+
284
+      ERROR("No session factory");
285
+      AmSipDialog::reply_error(req,500,"No session factory");
286
+
287
+      return NULL;
378 288
   }
379
-	    
289
+
380 290
   AmSession* session = NULL;
381 291
   if (req.method == "INVITE") {
382 292
     if (NULL != session_params) 
383
-      session = state_factory->onInvite(req, *session_params);
293
+      session = session_factory->onInvite(req, *session_params);
384 294
     else 
385
-      session = state_factory->onInvite(req);
295
+      session = session_factory->onInvite(req);
386 296
   } else if (req.method == "REFER") {
387 297
     if (NULL != session_params) 
388
-      session = state_factory->onRefer(req, *session_params);
298
+      session = session_factory->onRefer(req, *session_params);
389 299
     else 
390
-      session = state_factory->onRefer(req);
300
+      session = session_factory->onRefer(req);
391 301
   }
392 302
 
393 303
   if(!session) {
394
-    //  State creation failed:
304
+    //  Session creation failed:
395 305
     //   application denied session creation
396 306
     //   or there was an error.
397 307
     //
398 308
     //  let's hope the createState function has replied...
399 309
     //  ... and do nothing !
400 310
 
401
-    DBG("onInvite returned NULL\n");
402
-    return 0;
311
+    DBG("onInvite/onRefer returned NULL\n");
403 312
   }
404
-    
405
-  //state_factory->configureSession(session);
406
-  //session->checkSessionExpires(req);
407 313
 
408 314
   return session;
409 315
 }
410 316
 
411
-bool AmSessionContainer::addSession_unsafe(const string& callid, 
412
-					   const string& remote_tag,
413
-					   const string& local_tag,
414
-					   AmSession* session)
415
-{
416
-  if(getSession(callid,remote_tag))
417
-    return false;
418
-
419
-  if (!remote_tag.empty())
420
-    as_id_lookup[callid+remote_tag] = local_tag;
421
-
422
-  return addSession_unsafe(local_tag,session);
423
-}
424
-
425
-bool AmSessionContainer::addSession_unsafe(const string& local_tag,
426
-					   AmSession* session)
427
-{
428
-  if(getSession(local_tag))
429
-    return false;
430
-  
431
-  //DBG("a_sessions['%s'] = session\n",local_tag.c_str());
432
-  a_sessions[local_tag] = session;
433
-  return true;
434
-}
435
-
436 317
 bool AmSessionContainer::addSession(const string& callid,
437 318
 				    const string& remote_tag,
438 319
 				    const string& local_tag,
439 320
 				    AmSession* session)
440 321
 {
441
-  as_mut.lock();
442
-  bool ret = addSession_unsafe(callid,remote_tag,local_tag,session);
443
-  as_mut.unlock();
444
-  return ret;
322
+    return AmEventDispatcher::instance()->
323
+	addEventQueue(local_tag,(AmEventQueue*)session,
324
+		      callid,remote_tag);
445 325
 }
446 326
 
447 327
 bool AmSessionContainer::addSession(const string& local_tag,
448 328
 				    AmSession* session)
449 329
 {
450
-  as_mut.lock();
451
-  bool ret = addSession_unsafe(local_tag,session);
452
-  as_mut.unlock();
453
-  return ret;
454
-}
455
-
456
-int AmSessionContainer::getSize()
457
-{
458
-  int res=0;
459
-  as_mut.lock();
460
-  res = a_sessions.size();
461
-  as_mut.unlock();
462
-
463
-  return res;
330
+    return AmEventDispatcher::instance()->
331
+	addEventQueue(local_tag,(AmEventQueue*)session);
464 332
 }
... ...
@@ -49,32 +49,8 @@ class AmSessionContainer : public AmThread
49 49
 {
50 50
   static AmSessionContainer* _SessionContainer;
51 51
 
52
-  // some typedefs ...
53
-  typedef std::map<string,AmSession*> SessionMap;
54
-  typedef SessionMap::iterator SessionMapIter;
55
-
56
-  typedef std::map<string,string>     Dictionnary;
57
-  typedef Dictionnary::iterator  DictIter;
58
-
59 52
   typedef std::queue<AmSession*>      SessionQueue;
60 53
 
61
-  /** 
62
-   * Container for active sessions 
63
-   * local tag -> session
64
-   */
65
-  SessionMap a_sessions;
66
-
67
-  /** 
68
-   * Call ID + remote tag -> local tag 
69
-   *  (needed for CANCELs and some provisionnal answers)
70
-   *  (UAS sessions only)
71
-   */
72
-  Dictionnary as_id_lookup;
73
-
74
-  /** Mutex to protect the active session container */
75
-  AmMutex    as_mut;
76
-
77
-
78 54
   /** Container for dead sessions */
79 55
   SessionQueue d_sessions;
80 56
   /** Mutex to protect the dead session container */
... ...
@@ -86,39 +62,6 @@ class AmSessionContainer : public AmThread
86 62
   /** We are a Singleton ! Avoid people to have their own instance. */
87 63
   AmSessionContainer();
88 64
 
89
-  /**
90
-   * Search the container for a session coresponding 
91
-   * to callid and remote_tag. (UAS only).
92
-   *
93
-   * @return the session related to callid & remote_tag
94
-   *         or NULL if none has been found.
95
-   */
96
-  AmSession* getSession(const string& callid, const string& remote_tag);
97
-
98
-  /**
99
-   * Search the container for a session coresponding to local_tag.
100
-   *
101
-   * @return the session related to local_tag 
102
-   *         or NULL if none has been found.
103
-   */
104
-  AmSession* getSession(const string& local_tag);
105
-
106
-  /**
107
-   * Adds a session to the container. (UAS only)
108
-   * @return true if the session is new within the container.
109
-   */
110
-  bool addSession_unsafe(const string& callid, 
111
-			 const string& remote_tag,
112
-			 const string& local_tag,
113
-			 AmSession* session);
114
-
115
-  /**
116
-   * Adds a session to the container.
117
-   * @return true if the session is new within the container.
118
-   */
119
-  bool addSession_unsafe(const string& local_tag,
120
-			 AmSession* session);
121
-
122 65
   /**
123 66
    * Tries to stop the session and queue it destruction.
124 67
    */
... ...
@@ -154,7 +97,7 @@ class AmSessionContainer : public AmThread
154 97
    * @return true if the session is new within the container.
155 98
    */
156 99
   bool addSession(const string& local_tag,
157
-		  AmSession* session);
100
+ 		  AmSession* session);
158 101
 
159 102
   /** 
160 103
    * Constructs a new session and adds it to the active session container. 
... ...
@@ -175,11 +118,6 @@ class AmSessionContainer : public AmThread
175 118
   void destroySession(AmSession* s);
176 119
   void destroySession(const string& local_tag);
177 120
 
178
-  /**
179
-   * Query the number of active sessions
180
-   */
181
-  int getSize();
182
-
183 121
   /**
184 122
    * post an event into the event queue of the identified dialog.
185 123
    * @return false if session doesn't exist 
... ...
@@ -1,3 +1,29 @@
1
+/*
2
+ * $Id: $
3
+ *
4
+ * Copyright (C) 2008 Raphael Coeffic
5
+ *
6
+ * This file is part of sems, a free SIP media server.
7
+ *
8
+ * sems is free software; you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation; either version 2 of the License, or
11
+ * (at your option) any later version
12
+ *
13
+ * For a license to use the ser software under conditions
14
+ * other than those described here, or to purchase support for this
15
+ * software, please contact iptel.org by e-mail at the following addresses:
16
+ *    info@iptel.org
17
+ *
18
+ * sems is distributed in the hope that it will be useful,
19
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
+ * GNU General Public License for more details.
22
+ *
23
+ * You should have received a copy of the GNU General Public License 
24
+ * along with this program; if not, write to the Free Software 
25
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26
+ */
1 27
 
2 28
 #include "AmSessionContainer.h"
3 29
 #include "AmSipDialog.h"
... ...
@@ -5,6 +31,7 @@
5 31
 #include "log.h"
6 32
 
7 33
 #include "AmSipDispatcher.h"
34
+#include "AmEventDispatcher.h"
8 35
 
9 36
 AmSipDispatcher *AmSipDispatcher::_instance;
10 37
 
... ...
@@ -15,13 +42,12 @@ AmSipDispatcher* AmSipDispatcher::instance()
15 42
 
16 43
 void AmSipDispatcher::handleSipMsg(AmSipReply &reply)
17 44
 {
18
-  if (!AmSessionContainer::instance()->postEvent(reply.local_tag,
19
-      new AmSipReplyEvent(reply))) {
20
-    for (vector<AmSIPEventHandler*>::iterator it = 
21
-        reply_handlers.begin(); it != reply_handlers.end(); it++) 
22
-      if ((*it)->onSipReply(reply))
23
-        break;
24
-  }
45
+    AmSipReplyEvent* ev = new AmSipReplyEvent(reply);
46
+    if(!AmEventDispatcher::instance()->post(reply.local_tag,ev)){
47
+	
48
+	ERROR("could not dispatch reply\n");
49
+	delete ev;
50
+    }
25 51
 }
26 52
 
27 53
 void AmSipDispatcher::handleSipMsg(AmSipRequest &req)
... ...
@@ -30,44 +56,46 @@ void AmSipDispatcher::handleSipMsg(AmSipRequest &req)
30 56
   string remote_tag = req.from_tag;
31 57
   string local_tag  = req.to_tag;
32 58
 
33
-  bool sess_exists;
34
-  AmSipRequestEvent* ev = new AmSipRequestEvent(req);
35
-  AmSessionContainer* sess_cont = AmSessionContainer::instance();
36
-
37
-  if(local_tag.empty())
38
-    sess_exists = sess_cont->postEvent(callid,remote_tag,ev);
39
-  else
40
-    sess_exists = sess_cont->postEvent(local_tag,ev);
59
+  AmEventDispatcher* ev_disp = AmEventDispatcher::instance();
41 60
 
42
-  if(!sess_exists){
43
-		
44
-    DBG("method: `%s' [%zd].\n", req.method.c_str(), req.method.length());
45
-    
46
-    if((req.method == "INVITE")){
61
+  if(!local_tag.empty()) {
62
+    AmSipRequestEvent* ev = new AmSipRequestEvent(req);
47 63
 
48
-      sess_cont->startSessionUAS(req);
49
-    }
50
-    else if(req.method == "OPTIONS"){
51
-	
52
-	// Basic OPTIONS support
53
-	AmSipDialog::reply_error(req,200,"OK");
54
-	return;
55
-    }
56
-    else {
64
+      if(!ev_disp->post(local_tag,ev)) {
57 65
 
58
-      if(!local_tag.empty() || req.method == "CANCEL"){
66
+	  delete ev;
67
+	  
68
+	  AmSipDialog::reply_error(req,481,
69
+	      "Call leg/Transaction does not exist");
70
+      }
59 71
 
60
-        AmSipDialog::reply_error(req,481,
61
-          "Call leg/Transaction does not exist");
72
+      return;
73
+  }
62 74
 
63
-      } else {
75
+  if(ev_disp->postSipRequest(callid, remote_tag, req)){
76
+	  
77
+      return;
78
+  }
79
+  
80
+  DBG("method: `%s' [%zd].\n", req.method.c_str(), req.method.length());
81
+  
82
+  if((req.method == "INVITE")){
83
+      
84
+      AmSessionContainer::instance()->startSessionUAS(req);
85
+  }
86
+  else if(req.method == "OPTIONS"){
87
+      
88
+      // Basic OPTIONS support
89
+      AmSipDialog::reply_error(req,200,"OK");
90
+      return;
91
+  }
92
+  else {
64 93
 
65
-        ERROR("sorry, we don't support beginning a new session with "
66
-          "a '%s' message\n", req.method.c_str());
94
+      AmSessionFactory* sess_fact = AmPlugIn::instance()->findSessionFactory(req);
95
+      if(!sess_fact){
67 96
 
68
-        AmSipDialog::reply_error(req,501,"Not Implemented");
69
-        return;
97
+	  AmSipDialog::reply_error(req,500,"Not implemented");
98
+	  return;
70 99
       }
71
-    }
72 100
   }
73 101
 }
... ...
@@ -1,30 +1,43 @@
1
+/*
2
+ * $Id: $
3
+ *
4
+ * Copyright (C) 2008 Raphael Coeffic
5
+ *
6
+ * This file is part of sems, a free SIP media server.