This file is indexed.

/usr/include/pjsip-ua/sip_replaces.h is in libpjproject-dev 2.7.2~dfsg-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
/* $Id: sip_replaces.h 5241 2016-02-05 04:29:17Z nanang $ */
/* 
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 */
#ifndef __PJSIP_REPLACES_H__
#define __PJSIP_REPLACES_H__


/**
 * @file sip_replaces.h
 * @brief SIP Replaces support (RFC 3891 - SIP "Replaces" Header)
 */
#include <pjsip/sip_msg.h>

/**
 * @defgroup PJSIP_REPLACES SIP Replaces support (RFC 3891 - "Replaces" Header)
 * @ingroup PJSIP_HIGH_UA
 * @brief SIP Replaces support (RFC 3891 - "Replaces" Header)
 * @{
 *
 * This module implements support for Replaces header in PJSIP. The Replaces
 * specification is written in RFC 3891 - The Session Initiation Protocol (SIP) 
 * "Replaces" Header, and can be used to enable a variety of features, 
 * for example: "Attended Transfer" and "Call Pickup".
 *
 * 
 *
 * \section PJSIP_REPLACES_USING_SEC Using PJSIP Replaces Support
 *
 * \subsection PJSIP_REPLACES_INIT_SUBSEC Initialization
 *
 * Application needs to call #pjsip_replaces_init_module() during application
 * initialization stage to register "replaces" support in PJSIP. 
 *
 *
 * 
 * \subsection PJSIP_REPLACES_UAC_SUBSEC UAC Behavior: Sending a Replaces Header
 *
 * A User Agent that wishes to replace a single existing early or
 * confirmed dialog with a new dialog of its own, MAY send the target
 * User Agent an INVITE request containing a Replaces header field.  The
 * User Agent Client (UAC) places the Call-ID, to-tag, and from-tag
 * information for the target dialog in a single Replaces header field
 * and sends the new INVITE to the target.
 *
 * To initiate outgoing INVITE request with Replaces header, application
 * would create the INVITE request with #pjsip_inv_invite(), then adds
 * #pjsip_replaces_hdr instance into the request, filling up the Call-ID,
 * To-tag, and From-tag properties of the header with the identification
 * of the dialog to be replaced. Application may also optionally
 * set the \a early_only property of the header to indicate that it only
 * wants to replace early dialog.
 *
 * Note that when the outgoing INVITE request (with Replaces) is initiated
 * from an incoming REFER request (as in Attended Call Transfer case),
 * this process should be done rather more automatically by PJSIP. Upon 
 * receiving incoming incoming REFER request, normally these processes
 * will be performed:
 *  - Application finds \a Refer-To header,
 *  - Application creates outgoing dialog/invite session, specifying
 *    the URI in the \a Refer-To header as the initial remote target,
 *  - The URI in the \a Refer-To header may contain header parameters such
 *    as \a Replaces and \a Require headers.
 *  - The dialog keeps the header fields in the header parameters
 *    of the URI, and the invite session would add these headers into
 *    the outgoing INVITE request. Because of this, the outgoing 
 *    INVITE request will contain the \a Replaces and \a Require headers.
 *
 *
 * For more information, please see the implementation of 
 * #pjsua_call_xfer_replaces() in \ref PJSUA_LIB source code.
 *
 *
 * \subsection PJSIP_REPLACES_UAS_SUBSEC UAS Behavior: Receiving a Replaces Header
 *
 * The Replaces header contains information used to match an existing
 * SIP dialog (call-id, to-tag, and from-tag).  Upon receiving an INVITE
 * with a Replaces header, the User Agent (UA) attempts to match this
 * information with a confirmed or early dialog.  
 *
 * In PJSIP, if application wants to process the Replaces header in the
 * incoming INVITE request, it should call #pjsip_replaces_verify_request()
 * before creating the INVITE session. The #pjsip_replaces_verify_request()
 * function checks and verifies the request to see if Replaces request
 * can be processed. To be more specific, it performs the following
 * verification:
 *  - checks that Replaces header is present. If not, the function will
 *    return PJ_SUCCESS without doing anything.
 *  - checks that no duplicate Replaces headers are present, or otherwise
 *    it will return 400 "Bad Request" response.
 *  - checks for matching dialog and verifies that the invite session has
 *    the correct state, and may return 481 "Call/Transaction Does Not Exist",
 *    603 "Declined", or 486 "Busy Here" according to the processing rules
 *    specified in RFC 3891.
 *  - if matching dialog with correct state is found, it will give PJ_SUCCESS
 *    status and return the matching dialog back to the application.
 *
 * The following pseudocode illustrates how application can process the
 * incoming INVITE if it wants to support Replaces extension:
 *
 \code
  // Incoming INVITE request handler
  pj_bool_t on_rx_invite(pjsip_rx_data *rdata)
  {
    pjsip_dialog *dlg, *replaced_dlg;
    pjsip_inv_session *inv;
    pjsip_tx_data *response;
    pj_status_t status;

    // Check whether Replaces header is present in the request and process accordingly.
    //
    status = pjsip_replaces_verify_request(rdata, &replaced_dlg, PJ_FALSE, &response);
    if (status != PJ_SUCCESS) {
	// Something wrong with Replaces request.
	//
	if (response) {
	    pjsip_endpt_send_response(endpt, rdata, response, NULL, NULL);
	} else {
	    // Respond with 500 (Internal Server Error)
	    pjsip_endpt_respond_stateless(endpt, rdata, 500, NULL, NULL, NULL);
	}
    }

    // Create UAS Invite session as usual.
    //
    status = pjsip_dlg_create_uas_and_inc_lock(.., rdata, .., &dlg);
    ..
    status = pjsip_inv_create_uas(dlg, .., &inv);

    // Send initial 100 "Trying" to the INVITE request
    //
    status = pjsip_inv_initial_answer(inv, rdata, 100, ..., &response);
    if (status == PJ_SUCCESS)
	pjsip_inv_send_msg(inv, response);


    // This is where processing is different between normal call
    // (without Replaces) and call with Replaces.
    //
    if (replaced_dlg) {
	pjsip_inv_session *replaced_inv;

	// Always answer the new INVITE with 200, regardless whether
	// the replaced call is in early or confirmed state.
	//
	status = pjsip_inv_answer(inv, 200, NULL, NULL, &response);
	if (status == PJ_SUCCESS)
	    pjsip_inv_send_msg(inv, response);


	// Get the INVITE session associated with the replaced dialog.
	//
	replaced_inv = pjsip_dlg_get_inv_session(replaced_dlg);


	// Disconnect the "replaced" INVITE session.
	//
	status = pjsip_inv_end_session(replaced_inv, PJSIP_SC_GONE, NULL, &tdata);
	if (status == PJ_SUCCESS && tdata)
	    status = pjsip_inv_send_msg(replaced_inv, tdata);


	// It's up to application to associate the new INVITE session
	// with the old (now terminated) session. For example, application
	// may assign the same User Interface object for the new INVITE
	// session.

    } else {
	// Process normal INVITE without Replaces.
	...
    }
  }

 \endcode
 *
 *
 * For a complete sample implementation, please see \a pjsua_call_on_incoming()
 * function of \ref PJSUA_LIB in \a pjsua_call.c file.
 *
 *
 * \section PJSIP_REPLACES_REFERENCE References
 *
 * References:
 *  - <A HREF="http://www.ietf.org/rfc/rfc3891.txt">RFC 3891: The Session 
 *    Initiation Protocol (SIP) "Replaces" Header</A>
 *  - \ref PJSUA_XFER
 */

PJ_BEGIN_DECL


/**
 * Declaration of SIP Replaces header (RFC 3891).
 */
typedef struct pjsip_replaces_hdr
{
    /** Standard header field. */
    PJSIP_DECL_HDR_MEMBER(struct pjsip_replaces_hdr);

    /** Call-Id */
    pj_str_t	call_id;

    /** to-tag */
    pj_str_t	to_tag;

    /** from-tag */
    pj_str_t	from_tag;

    /** early-only? */
    pj_bool_t	early_only;

    /** Other parameters */
    pjsip_param	other_param;

} pjsip_replaces_hdr;



/**
 * Initialize Replaces support in PJSIP. This would, among other things, 
 * register the header parser for Replaces header.
 *
 * @param endpt	    The endpoint instance.
 *
 * @return	    PJ_SUCCESS on success.
 */
PJ_DECL(pj_status_t) pjsip_replaces_init_module(pjsip_endpoint *endpt);


/**
 * Create Replaces header.
 *
 * @param pool	    Pool to allocate the header instance from.
 *
 * @return	    An empty Replaces header instance.
 */
PJ_DECL(pjsip_replaces_hdr*) pjsip_replaces_hdr_create(pj_pool_t *pool);


/**
 * Verify that incoming request with Replaces header can be processed.
 * This function will perform all necessary checks according to RFC 3891
 * Section 3 "User Agent Server Behavior: Receiving a Replaces Header".
 *
 * @param rdata	    The incoming request to be verified.
 * @param p_dlg	    On return, it will be filled with the matching 
 *		    dialog.
 * @param lock_dlg  Specifies whether this function should acquire lock
 *		    to the matching dialog. If yes (and should be yes!),
 *		    then application will need to release the dialog's
 *		    lock with #pjsip_dlg_dec_lock() when the function
 *		    returns PJ_SUCCESS and the \a p_dlg parameter is filled
 *		    with the dialog instance.
 * @param p_tdata   Upon error, it will be filled with the final response
 *		    to be sent to the request sender.
 *
 * @return	    The function returns the following:
 *		    - If the request doesn't contain Replaces header, the
 *		      function returns PJ_SUCCESS and \a p_dlg parameter
 *		      will be set to NULL.
 *		    - If the request contains Replaces header and a valid,
 *		      matching dialog is found, the function returns 
 *		      PJ_SUCCESS and \a p_dlg parameter will be set to the
 *		      matching dialog instance.
 *		    - Upon error condition (as described by RFC 3891), the
 *		      function returns non-PJ_SUCCESS, and \a p_tdata 
 *		      parameter SHOULD be set with a final response message
 *		      to be sent to the sender of the request.
 */
PJ_DECL(pj_status_t) pjsip_replaces_verify_request(pjsip_rx_data *rdata,
						   pjsip_dialog **p_dlg,
						   pj_bool_t lock_dlg,
						   pjsip_tx_data **p_tdata);



PJ_END_DECL


/**
 * @}
 */


#endif	/* __PJSIP_REPLACES_H__ */