Add support for ICE/STUN/TURN in res_rtp_asterisk and chan_sip.
[asterisk/asterisk.git] / res / pjproject / pjsip / include / pjsip-ua / sip_replaces.h
1 /* $Id$ */
2 /* 
3  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4  * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
5  *
6  * This program 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.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
19  */
20 #ifndef __PJSIP_REPLACES_H__
21 #define __PJSIP_REPLACES_H__
22
23
24 /**
25  * @file sip_replaces.h
26  * @brief SIP Replaces support (RFC 3891 - SIP "Replaces" Header)
27  */
28 #include <pjsip/sip_msg.h>
29
30 /**
31  * @defgroup PJSIP_REPLACES SIP Replaces support (RFC 3891 - "Replaces" Header)
32  * @ingroup PJSIP_HIGH_UA
33  * @brief SIP Replaces support (RFC 3891 - "Replaces" Header)
34  * @{
35  *
36  * This module implements support for Replaces header in PJSIP. The Replaces
37  * specification is written in RFC 3891 - The Session Initiation Protocol (SIP) 
38  * "Replaces" Header, and can be used to enable a variety of features, 
39  * for example: "Attended Transfer" and "Call Pickup".
40  *
41  * 
42  *
43  * \section PJSIP_REPLACES_USING_SEC Using PJSIP Replaces Support
44  *
45  * \subsection PJSIP_REPLACES_INIT_SUBSEC Initialization
46  *
47  * Application needs to call #pjsip_replaces_init_module() during application
48  * initialization stage to register "replaces" support in PJSIP. 
49  *
50  *
51  * 
52  * \subsection PJSIP_REPLACES_UAC_SUBSEC UAC Behavior: Sending a Replaces Header
53  *
54  * A User Agent that wishes to replace a single existing early or
55  * confirmed dialog with a new dialog of its own, MAY send the target
56  * User Agent an INVITE request containing a Replaces header field.  The
57  * User Agent Client (UAC) places the Call-ID, to-tag, and from-tag
58  * information for the target dialog in a single Replaces header field
59  * and sends the new INVITE to the target.
60  *
61  * To initiate outgoing INVITE request with Replaces header, application
62  * would create the INVITE request with #pjsip_inv_invite(), then adds
63  * #pjsip_replaces_hdr instance into the request, filling up the Call-ID,
64  * To-tag, and From-tag properties of the header with the identification
65  * of the dialog to be replaced. Application may also optionally
66  * set the \a early_only property of the header to indicate that it only
67  * wants to replace early dialog.
68  *
69  * Note that when the outgoing INVITE request (with Replaces) is initiated
70  * from an incoming REFER request (as in Attended Call Transfer case),
71  * this process should be done rather more automatically by PJSIP. Upon 
72  * receiving incoming incoming REFER request, normally these processes
73  * will be performed:
74  *  - Application finds \a Refer-To header,
75  *  - Application creates outgoing dialog/invite session, specifying
76  *    the URI in the \a Refer-To header as the initial remote target,
77  *  - The URI in the \a Refer-To header may contain header parameters such
78  *    as \a Replaces and \a Require headers.
79  *  - The dialog keeps the header fields in the header parameters
80  *    of the URI, and the invite session would add these headers into
81  *    the outgoing INVITE request. Because of this, the outgoing 
82  *    INVITE request will contain the \a Replaces and \a Require headers.
83  *
84  *
85  * For more information, please see the implementation of 
86  * #pjsua_call_xfer_replaces() in \ref PJSUA_LIB source code.
87  *
88  *
89  * \subsection PJSIP_REPLACES_UAS_SUBSEC UAS Behavior: Receiving a Replaces Header
90  *
91  * The Replaces header contains information used to match an existing
92  * SIP dialog (call-id, to-tag, and from-tag).  Upon receiving an INVITE
93  * with a Replaces header, the User Agent (UA) attempts to match this
94  * information with a confirmed or early dialog.  
95  *
96  * In PJSIP, if application wants to process the Replaces header in the
97  * incoming INVITE request, it should call #pjsip_replaces_verify_request()
98  * before creating the INVITE session. The #pjsip_replaces_verify_request()
99  * function checks and verifies the request to see if Replaces request
100  * can be processed. To be more specific, it performs the following
101  * verification:
102  *  - checks that Replaces header is present. If not, the function will
103  *    return PJ_SUCCESS without doing anything.
104  *  - checks that no duplicate Replaces headers are present, or otherwise
105  *    it will return 400 "Bad Request" response.
106  *  - checks for matching dialog and verifies that the invite session has
107  *    the correct state, and may return 481 "Call/Transaction Does Not Exist",
108  *    603 "Declined", or 486 "Busy Here" according to the processing rules
109  *    specified in RFC 3891.
110  *  - if matching dialog with correct state is found, it will give PJ_SUCCESS
111  *    status and return the matching dialog back to the application.
112  *
113  * The following pseudocode illustrates how application can process the
114  * incoming INVITE if it wants to support Replaces extension:
115  *
116  \code
117   // Incoming INVITE request handler
118   pj_bool_t on_rx_invite(pjsip_rx_data *rdata)
119   {
120     pjsip_dialog *dlg, *replaced_dlg;
121     pjsip_inv_session *inv;
122     pjsip_tx_data *response;
123     pj_status_t status;
124
125     // Check whether Replaces header is present in the request and process accordingly.
126     //
127     status = pjsip_replaces_verify_request(rdata, &replaced_dlg, PJ_FALSE, &response);
128     if (status != PJ_SUCCESS) {
129         // Something wrong with Replaces request.
130         //
131         if (response) {
132             pjsip_endpt_send_response(endpt, rdata, response, NULL, NULL);
133         } else {
134             // Respond with 500 (Internal Server Error)
135             pjsip_endpt_respond_stateless(endpt, rdata, 500, NULL, NULL, NULL);
136         }
137     }
138
139     // Create UAS Invite session as usual.
140     //
141     status = pjsip_dlg_create_uas(.., rdata, .., &dlg);
142     ..
143     status = pjsip_inv_create_uas(dlg, .., &inv);
144
145     // Send initial 100 "Trying" to the INVITE request
146     //
147     status = pjsip_inv_initial_answer(inv, rdata, 100, ..., &response);
148     if (status == PJ_SUCCESS)
149         pjsip_inv_send_msg(inv, response);
150
151
152     // This is where processing is different between normal call
153     // (without Replaces) and call with Replaces.
154     //
155     if (replaced_dlg) {
156         pjsip_inv_session *replaced_inv;
157
158         // Always answer the new INVITE with 200, regardless whether
159         // the replaced call is in early or confirmed state.
160         //
161         status = pjsip_inv_answer(inv, 200, NULL, NULL, &response);
162         if (status == PJ_SUCCESS)
163             pjsip_inv_send_msg(inv, response);
164
165
166         // Get the INVITE session associated with the replaced dialog.
167         //
168         replaced_inv = pjsip_dlg_get_inv_session(replaced_dlg);
169
170
171         // Disconnect the "replaced" INVITE session.
172         //
173         status = pjsip_inv_end_session(replaced_inv, PJSIP_SC_GONE, NULL, &tdata);
174         if (status == PJ_SUCCESS && tdata)
175             status = pjsip_inv_send_msg(replaced_inv, tdata);
176
177
178         // It's up to application to associate the new INVITE session
179         // with the old (now terminated) session. For example, application
180         // may assign the same User Interface object for the new INVITE
181         // session.
182
183     } else {
184         // Process normal INVITE without Replaces.
185         ...
186     }
187   }
188
189  \endcode
190  *
191  *
192  * For a complete sample implementation, please see \a pjsua_call_on_incoming()
193  * function of \ref PJSUA_LIB in \a pjsua_call.c file.
194  *
195  *
196  * \section PJSIP_REPLACES_REFERENCE References
197  *
198  * References:
199  *  - <A HREF="http://www.ietf.org/rfc/rfc3891.txt">RFC 3891: The Session 
200  *    Initiation Protocol (SIP) "Replaces" Header</A>
201  *  - \ref PJSUA_XFER
202  */
203
204 PJ_BEGIN_DECL
205
206
207 /**
208  * Declaration of SIP Replaces header (RFC 3891).
209  */
210 typedef struct pjsip_replaces_hdr
211 {
212     /** Standard header field. */
213     PJSIP_DECL_HDR_MEMBER(struct pjsip_replaces_hdr);
214
215     /** Call-Id */
216     pj_str_t    call_id;
217
218     /** to-tag */
219     pj_str_t    to_tag;
220
221     /** from-tag */
222     pj_str_t    from_tag;
223
224     /** early-only? */
225     pj_bool_t   early_only;
226
227     /** Other parameters */
228     pjsip_param other_param;
229
230 } pjsip_replaces_hdr;
231
232
233
234 /**
235  * Initialize Replaces support in PJSIP. This would, among other things, 
236  * register the header parser for Replaces header.
237  *
238  * @param endpt     The endpoint instance.
239  *
240  * @return          PJ_SUCCESS on success.
241  */
242 PJ_DECL(pj_status_t) pjsip_replaces_init_module(pjsip_endpoint *endpt);
243
244
245 /**
246  * Create Replaces header.
247  *
248  * @param pool      Pool to allocate the header instance from.
249  *
250  * @return          An empty Replaces header instance.
251  */
252 PJ_DECL(pjsip_replaces_hdr*) pjsip_replaces_hdr_create(pj_pool_t *pool);
253
254
255 /**
256  * Verify that incoming request with Replaces header can be processed.
257  * This function will perform all necessary checks according to RFC 3891
258  * Section 3 "User Agent Server Behavior: Receiving a Replaces Header".
259  *
260  * @param rdata     The incoming request to be verified.
261  * @param p_dlg     On return, it will be filled with the matching 
262  *                  dialog.
263  * @param lock_dlg  Specifies whether this function should acquire lock
264  *                  to the matching dialog. If yes (and should be yes!),
265  *                  then application will need to release the dialog's
266  *                  lock with #pjsip_dlg_dec_lock() when the function
267  *                  returns PJ_SUCCESS and the \a p_dlg parameter is filled
268  *                  with the dialog instance.
269  * @param p_tdata   Upon error, it will be filled with the final response
270  *                  to be sent to the request sender.
271  *
272  * @return          The function returns the following:
273  *                  - If the request doesn't contain Replaces header, the
274  *                    function returns PJ_SUCCESS and \a p_dlg parameter
275  *                    will be set to NULL.
276  *                  - If the request contains Replaces header and a valid,
277  *                    matching dialog is found, the function returns 
278  *                    PJ_SUCCESS and \a p_dlg parameter will be set to the
279  *                    matching dialog instance.
280  *                  - Upon error condition (as described by RFC 3891), the
281  *                    function returns non-PJ_SUCCESS, and \a p_tdata 
282  *                    parameter SHOULD be set with a final response message
283  *                    to be sent to the sender of the request.
284  */
285 PJ_DECL(pj_status_t) pjsip_replaces_verify_request(pjsip_rx_data *rdata,
286                                                    pjsip_dialog **p_dlg,
287                                                    pj_bool_t lock_dlg,
288                                                    pjsip_tx_data **p_tdata);
289
290
291
292 PJ_END_DECL
293
294
295 /**
296  * @}
297  */
298
299
300 #endif  /* __PJSIP_REPLACES_H__ */
301