1 /*
2  * Copyright (C) 2002-2003 Fhg Fokus
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 /** @file AmSipDialog.h */
28 #ifndef AmSipDialog_h
29 #define AmSipDialog_h
30 
31 #include "AmBasicSipDialog.h"
32 #include "AmSdp.h"
33 #include "AmOfferAnswer.h"
34 #include "Am100rel.h"
35 
36 class AmSipTimeoutEvent;
37 class AmSipDialogEventHandler;
38 
39 /**
40  * \brief implements the dialog state machine
41  */
42 class AmSipDialog
43   : public AmBasicSipDialog
44 {
45 protected:
46   // Number of open UAS INVITE transactions
47   unsigned int pending_invites;
48 
49   AmSdp   sdp_local;
50   AmSdp   sdp_remote;
51 
52   bool early_session_started;
53   bool session_started;
54 
55   // Current offer/answer transaction
56   AmOfferAnswer oa;
57   bool offeranswer_enabled;
58 
59   // Reliable provisional reply support
60   Am100rel rel100;
61 
62   int onTxReply(const AmSipRequest& req, AmSipReply& reply, int& flags);
63   int onTxRequest(AmSipRequest& req, int& flags);
64 
65   void onReplyTxed(const AmSipRequest& req, const AmSipReply& reply);
66   void onRequestTxed(const AmSipRequest& req);
67 
68   bool onRxReqSanity(const AmSipRequest& req);
69   bool onRxReqStatus(const AmSipRequest& req);
70 
71   bool onRxReplySanity(const AmSipReply& reply);
72   bool onRxReplyStatus(const AmSipReply& reply);
73 
74 
75  public:
76 
77   AmSipDialog(AmSipDialogEventHandler* h=NULL);
78   ~AmSipDialog();
79 
80   /** @return whether UAC INVITE transaction is pending */
81   bool   getUACInvTransPending();
82 
83   /** @return a pending UAS INVITE transaction or NULL */
84   AmSipRequest* getUASPendingInv();
85 
86   /**
87    * Calls onSdpCompleted on the session event handler
88    * and executes onSessionStart/onEarlySessionStart when required.
89    */
90   int onSdpCompleted();
91 
92   bool getSdpOffer(AmSdp& offer);
93   bool getSdpAnswer(const AmSdp& offer, AmSdp& answer);
94 
95   AmOfferAnswer::OAState getOAState();
96   void setOAState(AmOfferAnswer::OAState n_st);
97   void setOAEnabled(bool oa_enabled);
getLocalSdp()98   const AmSdp& getLocalSdp() { return oa.getLocalSdp(); }
getRemoteSdp()99   const AmSdp& getRemoteSdp() { return oa.getRemoteSdp(); }
100 
101   void setRel100State(Am100rel::State rel100_state);
102 
103   void uasTimeout(AmSipTimeoutEvent* to_ev);
104 
105   /** @return 0 on success */
106   int send_200_ack(unsigned int inv_cseq,
107 		   const AmMimeBody* body = NULL,
108 		   const string& hdrs = "",
109 		   int flags = 0);
110 
111   /** @return 0 on success */
112   int bye(const string& hdrs = "", int flags = 0);
113 
114   /** @return 0 on success */
115   int cancel();
116   int cancel(const string& hdrs);
117 
118   /** @return 0 on success */
119   int prack(const AmSipReply &reply1xx,
120 	    const AmMimeBody* body,
121             const string &hdrs);
122 
123   /** @return 0 on success */
124   int update(const AmMimeBody* body,
125             const string &hdrs);
126 
127   /** @return 0 on success */
128   int reinvite(const string& hdrs,
129 	       const AmMimeBody* body,
130 	       int flags = 0);
131 
132   /** @return 0 on success */
133   int invite(const string& hdrs,
134 	     const AmMimeBody* body);
135 
136   /** @return 0 on success */
137   int refer(const string& refer_to,
138 	    int expires = -1,
139 	    const string& referred_by = "",
140 	    const string& extrahdrs = "");
141 
142   /** @return 0 on success */
143   int info(const string& hdrs,
144 	   const AmMimeBody* body);
145 
146   /** @return 0 on success */
147   int transfer(const string& target);
148   int drop();
149 };
150 
151 /**
152  * \brief base class for SIP request/reply event handler
153  */
154 class AmSipDialogEventHandler
155   : public AmBasicSipEventHandler
156 {
157 public:
158   /** Hook called when a provisional reply is received with 100rel active */
159   virtual void onInvite1xxRel(const AmSipReply &)=0;
160 
161   /** Hook called when a local INVITE request has been replied with 2xx */
162   virtual void onInvite2xx(const AmSipReply& reply)=0;
163 
164   /** Hook called when an answer for a locally sent PRACK is received */
165   virtual void onPrack2xx(const AmSipReply &)=0;
166 
167   /** Hook called when a UAS INVITE transaction did not receive the ACK */
168   virtual void onNoAck(unsigned int ack_cseq)=0;
169 
170   /** Hook called when a UAS INVITE transaction did not receive the PRACK */
171   virtual void onNoPrack(const AmSipRequest &req, const AmSipReply &rpl)=0;
172 
173   /** Hook called when an SDP offer is required */
174   virtual bool getSdpOffer(AmSdp& offer)=0;
175 
176   /** Hook called when an SDP offer is required */
177   virtual bool getSdpAnswer(const AmSdp& offer, AmSdp& answer)=0;
178 
179   /** Hook called when an SDP OA transaction has been completed */
180   virtual int onSdpCompleted(const AmSdp& local, const AmSdp& remote)=0;
181 
182   /** Hook called when an early session starts
183    *  (SDP OA completed + dialog in early state) */
184   virtual void onEarlySessionStart()=0;
185 
186   /** Hook called when the session creation is completed
187    *  (INV trans replied with 200) */
188   virtual void onSessionStart()=0;
189 
~AmSipDialogEventHandler()190   virtual ~AmSipDialogEventHandler() {};
191 };
192 
193 #endif
194 
195 /** EMACS **
196  * Local variables:
197  * mode: c++
198  * c-basic-offset: 2
199  * End:
200  */
201