1 /*
2  * Copyright (C) 2012 Frafos GmbH
3  *
4  * This file is part of SEMS, a free SIP media server.
5  *
6  * SEMS is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version. This program is released under
10  * the GPL with the additional exemption that compiling, linking,
11  * and/or using OpenSSL is allowed.
12  *
13  * For a license to use the SEMS 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 _SBCSimpleRelay_h_
28 #define _SBCSimpleRelay_h_
29 
30 #include "atomic_types.h"
31 #include "AmBasicSipDialog.h"
32 #include "AmSipSubscription.h"
33 #include "AmEventQueue.h"
34 
35 #include "SBC.h"
36 #include "ExtendedCCInterface.h"
37 
38 #include "ampi/UACAuthAPI.h"
39 
40 #include <map>
41 #include <list>
42 using std::map;
43 
44 class SimpleRelayDialog
45   : public AmBasicSipDialog,
46     public AmBasicSipEventHandler,
47     public AmEventQueue,
48     public AmEventHandler,
49     public DialogControl,
50     public CredentialHolder
51 {
52   atomic_ref_cnt*     parent_obj;
53   string              other_dlg;
54 
55   // mediation stuff
56   vector<FilterEntry>  headerfilter;
57   string               append_headers;
58   ReplyTranslationMap  reply_translations;
59   bool                 transparent_dlg_id;
60   bool                 keep_vias;
61   bool                 fix_replaces_ref;
62 
63   bool finished;
64 
65   struct CCModuleInfo {
66     ExtendedCCInterface* module;
67     void *user_data;
68   };
69   std::list<CCModuleInfo> cc_ext;
70 
71   // auth support
72   std::unique_ptr<UACAuthCred>           auth_cred;
73   std::unique_ptr<AmSessionEventHandler> auth_h;
74 
getCredentials()75   UACAuthCred* getCredentials() { return auth_cred.get(); }
getDlg()76   AmBasicSipDialog* getDlg() { return this; }
77 
78   // relay methods
79   int relayRequest(const AmSipRequest& req);
80   int relayReply(const AmSipReply& reply);
81 
82 protected:
83   typedef map<unsigned int,unsigned int> RelayMap;
84   RelayMap relayed_reqs;
85 
86   // AmEventHandler
87   void process(AmEvent* ev);
88 
89   // AmEventQueue
90   bool processingCycle();
91 
92   void initCCModules(SBCCallProfile &profile, vector<AmDynInvoke*> &cc_modules);
93 
94   virtual void onB2BRequest(const AmSipRequest& req);
95   virtual void onB2BReply(const AmSipReply& reply);
96 
97   /** correctly terminate the dialog; MUST be redefined if "terminated" method
98    * is redefined */
terminate()99   virtual void terminate() { finished = true; }
100 
101 public:
102   SimpleRelayDialog(SBCCallProfile &profile, vector<AmDynInvoke*> &cc_modules,
103 		    atomic_ref_cnt* parent_obj=NULL);
104   SimpleRelayDialog(atomic_ref_cnt* parent_obj=NULL);
105   ~SimpleRelayDialog();
106 
setParent(atomic_ref_cnt * p_obj)107   void setParent(atomic_ref_cnt* p_obj) {
108     if(parent_obj) dec_ref(parent_obj);
109     if(p_obj) inc_ref(p_obj);
110     parent_obj = p_obj;
111   }
112 
setOtherDlg(const string & dlg)113   void setOtherDlg(const string& dlg) {
114     other_dlg = dlg;
115   }
116 
getOtherDlg()117   const string& getOtherDlg() {
118     return other_dlg;
119   }
120 
setKeepVias(bool kv)121   void setKeepVias(bool kv) {
122     keep_vias = kv;
123   }
124 
getKeepVias()125   bool getKeepVias() {
126     return keep_vias;
127   }
128 
getHeaderFilter()129   vector<FilterEntry>&  getHeaderFilter() { return headerfilter; }
getHeaderFilter()130   const vector<FilterEntry>&  getHeaderFilter() const { return headerfilter; }
131 
getAppendHeaders()132   string& getAppendHeaders() { return append_headers; }
getAppendHeaders()133   const string& getAppendHeaders() const { return append_headers; }
134 
getReplyTranslations()135   ReplyTranslationMap&  getReplyTranslations() { return reply_translations; }
getReplyTranslations()136   const ReplyTranslationMap&  getReplyTranslations() const {
137     return reply_translations;
138   }
139 
140   virtual int initUAC(const AmSipRequest& req, const SBCCallProfile& cp);
141   virtual int initUAS(const AmSipRequest& req, const SBCCallProfile& cp);
142 
terminated()143   virtual bool terminated() { return finished; }
144 
145   // AmBasicSipEventHandler interface
146   void onSendRequest(AmSipRequest& req, int& flags);
147   void onSipRequest(const AmSipRequest& req);
148   void onSipReply(const AmSipRequest& req,
149 		  const AmSipReply& reply,
150 		  AmBasicSipDialog::Status old_dlg_status);
151   void onRequestSent(const AmSipRequest& req);
152   void onReplySent(const AmSipRequest& req, const AmSipReply& reply);
153 
154   void onRemoteDisappeared(const AmSipReply& reply);
155   void onLocalTerminate(const AmSipReply& reply);
156 
157   // AmEventQueue
158   void finalize();
159 };
160 
161 class SBCSimpleRelay
162 {
163 public:
164   static int start(const SimpleRelayCreator::Relay& relay,
165 		   const AmSipRequest& req,
166 		   const SBCCallProfile& cp);
167 };
168 
169 #endif
170