|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Detailed DescriptionThis 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". Using PJSIP Replaces SupportInitializationApplication needs to call pjsip_replaces_init_module() during application initialization stage to register "replaces" support in PJSIP. UAC Behavior: Sending a Replaces HeaderA 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 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:
For more information, please see the implementation of pjsua_call_xfer_replaces() in PJSUA API - High Level Softphone API source code. UAS Behavior: Receiving a Replaces HeaderThe 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:
The following pseudocode illustrates how application can process the incoming INVITE if it wants to support Replaces extension: // 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(.., 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. ... } } For a complete sample implementation, please see pjsua_call_on_incoming() function of PJSUA API - High Level Softphone API in pjsua_call.c file. ReferencesReferences:
Function Documentation
Initialize Replaces support in PJSIP. This would, among other things, register the header parser for Replaces header.
Create Replaces header.
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".
Copyright (C) 2006-2008 Teluu Inc.
| |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||