Changes between Version 4 and Version 5 of SIP_Redirection

Nov 27, 2008 10:57:07 AM (16 years ago)



  • SIP_Redirection

    v4 v5  
    1 = Processing Outgoing Call Redirection in PJSUA-LIB = 
     1= Processing Call Redirection (3xx) Response in PJSIP = 
    3 This article describes SIP redirection support in PJSUA-LIB, that is implemented by ticket #456. 
     3This article describes SIP redirection support in PJSIP, that is implemented by ticket #10 in release 1.0.1 (December 2008). 
    5 == Outgoing Call Redirection and Multiple Targets == 
     5The redirection in this article is about processing SIP redirect (3xx) response in outgoing calls, and not about sending redirection/3xx response. Sending 3xx response in PJSUA-LIB is easy; just use {{{pjsua_call_hangup()}}} and give the new targets in Contact header in {{{msg_data}}} parameter. 
    7 The redirection in this article is about following (or not) redirection response (SIP 3xx code) in outgoing call, and not about sending redirection/3xx response. Sending 3xx response in PJSUA-LIB is easy; just use {{{pjsua_call_hangup()}}} and give the new targets in Contact header in {{{msg_data}}} parameter. 
     7== Objectives == 
    9 The SIP redirection support in PJSUA-LIB is implemented as subset of generic multiple call targeting support. Multiple call targeting is a neat new feature in PJSUA-LIB that allows a single outgoing call to have multiple targets, which will be called sequentially until one of the target picks up the call. Some use cases of this feature are as follows. 
    11 === Redirection === 
    13 Redirection (by means of SIP 3xx response) is a natural use case of multiple call targeting. In this scenario, the original INVITE is rejected with redirection response (SIP 300-399 code) containing one or more targets (Contact header). Application then may instruct the call to follow the redirection, and the library will send a fresh INVITE request to the new target. This second INVITE may be redirected too, and once again application may instruct the call to follow the new target. And so on, the process continues until one of the target picks up the call, or all targets have been tried but none of them can accept the call, or the call has reached it's maximum number of targets allowed in a single call. 
    15 The process of retrying new targets will happen automatically without application having to make a new call (although it may do that if it wants to), and all invite requests belong to the same call id. That said, application still has the full control over accepting the redirection instruction. It may reject the redirection, it may accept it, it may accept only partial list of targets, and it may delay the acceptance if it wants to ask for user permission first. 
     9The redirected call handling is implemented by ticket #10. The objective statements of this work are: 
     10 - must be implemented in PJSIP level rather than PJSUA-LIB level 
     11 - must allow application to accept or reject the redirection request on a per-target basis (by means of callback) 
     12 - must allow application to defer the decision to accept or reject the redirection request (for example, to ask for user confirmation to accept or reject the target) 
     13 - the subsequent INVITE requests sent after the 3xx response must have the same To, From, and Call-ID as used by the original INVITE. While RFC 3261 only put this at RECOMMENDED strength (see section, in practice there are many servers out there that relies on this property. 
    18 === Multiple Call Targeting === 
     16== Implementation Details == 
    20 This is a neat feature of PJSUA-LIB, to give multiple targets to the outgoing call without having to receive 3xx response. Here is a sample use case. 
     18=== PJSIP === 
    22 Suppose you want to reach anybody in PJSIP, for example you have a show-stopper bug that needs to be fixed urgently. You do not care who should pick up the phone, all you care is that someone in PJSIP should answer your call (say, you are boiling mad that the application crashed, and you want somebody in PJSIP to hear about this). You know the SIP address of two persons in PJSIP, Perry and me. 
     20A new callback was added to the invite session callback ({{{pjsip_inv_callback}}}) in pjsip-ua library: 
    24 So you dial Perry's URI, and also configure the (same) call with my URI as alternate target. If Perry picks up the phone, good, you can offload your rants to him. If he doesn't pick up the phone, the call will go to its alternate target, which is me (as long as Perry doesn't also redirect the call to his voice mail). Of course this is bad news for me, but you, the customer, is happy, and that's the main thing. 
     22 {{{ 
     23    void (*on_redirected)(pjsip_inv_session *inv, const pjsip_uri *target, 
     24                          pjsip_redirect_op *cmd, const pjsip_event *e); 
     25 }}} 
     27Application '''MUST''' implement this callback if it wants the invite session to manage redirection. If this callback is not implemented, the invite session will be disconnected upon receipt of 3xx response. 
     29If this callback is implemented, the default behavior (that is when the callback contains no function body) is to follow the redirection. 
     31This callback is called when the invite session is being redirected to a new target. If there are multiple targets, then the callback will be called for each target. This function is called on these events: 
     32 - a 3xx response containing usable Contact header(s) is received 
     33 - a 4xx or 5xx response to subsequent INVITE request is received, and the invite session has at least one more valid target to try. This happens for example when multiple Contact headers (alternate targets) are received for the original INVITE, and 4xx/5xx response is received for the second INVITE (to the first alternate target). The callback then will be called before the invite session tries to send the third INVITE to the second alternate target. 
    27 == Configuring Multiple Targets == 
     36The arguments for this callback are as follows: 
     37 ''inv'':: 
     38   The invite session 
    29 Both call redirection and multiple call targets are done with the same function below: 
     40 ''target'':: 
     41   The current target URI to which the INVITE will be sent to. 
    31 {{{ 
    32   PJ_DECL(pj_status_t) pjsua_call_manage_target(pjsua_call_id call_id, 
    33                                                 const pj_str_t *target, 
    34                                                 pjsip_status_code tgt_code, 
    35                                                 const pj_str_t *referer, 
    36                                                 float qvalue, 
    37                                                 const pjsua_msg_data *msg_data); 
    38 }}} 
     43 ''cmd'':: 
     44   Tells the invite session about what to do with this redirection. The default value is to accept the redirection. Application can change this to the following valid values: 
     45     - ''PJSIP_REDIRECT_ACCEPT'': immediately accept the redirection (default value). The session will immediately resend INVITE request to the target upon return of this callback. 
     46     - ''PJSIP_REDIRECT_REJECT'': immediately reject this target. The session will continue retrying with next target if present (and it will call this callback again for the next target), or immediately disconnect the call if there is no more target to try (notifying the ''on_state_changed()'' callback as usual). 
     47     - ''PJSIP_REDIRECT_STOP'': stop the whole redirection process and immediately disconnect the call, regardless on whether there is other target to try or not.  
     48     - ''PJSIP_REDIRECT_PENDING'': set to this value if no decision can be made immediately (for example to request confirmation from user). Application then MUST call ''pjsip_inv_process_redirect()'' (see below) to either accept or reject the redirection upon getting user decision. 
    40 The parameters of the function are as follows: 
    42  ''call_id'':: 
    43     The call ID of an outgoing call which status is not disconnected yet. 
    44  ''target''::  
    45     Target URI. 
    46  ''tgt_code'':: 
    47     Operation to be applied to the target: 
    48      - value 100-199: the target will be added, but it will not be called until it's code is set to 2xx. 
    49      - value 200-299: the target will be added and called as soon as possible. 
    50      - value 300-699: the target will be removed from the list, if it's present. 
    51  ''referer''::  
    52     Optionally specify the URI of the referer, that is the URI of the original target which returned redirection response containing this target. This referer URI is used to calculate the priority of this new target. If referer is not used, the target priority will be calculated from the qvalue parameter instead. 
    53  ''qvalue'':: 
    54     Priority value, from 0 to 1. Target with lower priority number will be called first. If application specify zero, then this target will be selected first for the next call, and if 1, this target will be called last. 
    55  ''msg_data''::  
    56     Optional list of headers etc to be added to outgoing call to this target. 
     50 ''e'':: 
     51   The event that triggers this callback to be called. This could be of type {{{PJSIP_EVENT_TSX_STATE}}} containing receipt of 3xx, 4xx, or 5xx response, or any other type depending on what is passed to {{{pjsip_inv_process_redirect()}}} below, or of type {{{PJSIP_EVENT_USER}}} if this callback is called by {{{pjsip_inv_process_redirect()}}} below and the event argument to that function is NULL, or NULL. 
    59 Fore more information, please see the function documentation for details. 
     54A new function for the invite session ({{{pjsip_inv_session}}}) was also added: 
    61 === Redirection === 
     56 {{{ 
     57PJ_DECL(pj_status_t) pjsip_inv_process_redirect(pjsip_inv_session *inv, 
     58                                                pjsip_redirect_op cmd, 
     59                                                pjsip_event *e); 
     60 }}} 
    63 For call redirection, there is new callback in {{{pjsua_callback}}} to notify application about redirection response from callee: 
     62This function allows the application to notify the invite session about the result of user confirmation. 
    65 {{{ 
    66     void (*on_call_redirected)(pjsua_call_id call_id,  
    67                                unsigned target_cnt, 
    68                                const pj_str_t target[], 
    69                                pjsip_event *e); 
    70 }}} 
     64The event (''e'') argument is the event that will be passed to {{{on_redirected()}}} callback when the user rejects the redirection and there is another target to try. When NULL is passed to this argument, then the invite session will create {{{PJSIP_EVENT_USER}}} event with NULL values to pass to the callback. 
    72 Application would have to implement {{{on_call_redirected()}}} callback above, and call {{{pjsua_call_manage_target()}}} for each target that it wants the call to follow. As soon as the callback returns, the call will proceed with sending fresh invite to the new targets (provided that there is at least one target to try immediately. See pjsua_call_manage_target() documentation for more info). 
     66The redirection usage scenarios will be explained below. 
    74 === Configuring Alternate Targets === 
     68==== Accept Redirection to This Target ==== 
    76 For configuring alternate target to outgoing call without waiting for 3xx response, application can simply add the target with {{{pjsua_call_manage_target()}}} at any time before the call is disconnected (the best time would be immediately after making the call, if the alternate target has been known beforehand). This target will be tried as soon as the first target fails. 
     70Set the ''cmd'' argument of the callback to ''PJSIP_REDIRECT_ACCEPT'' to accept the redirection to this target. And INVITE session will be sent immediately to the target. 
     72==== Reject Redirection to This Target ==== 
     74Set the ''cmd'' argument of the callback to ''PJSIP_REDIRECT_REJECT'' to reject the redirection to this target. If there is another target to try, then the callback will be called again with this next target, otherwise the invite session will be disconnected immediately. 
     76==== Stop Redirection ==== 
     78Set the ''cmd'' argument of the callback to ''PJSIP_REDIRECT_STOP'' to stop the redirection process and disconnect the call immediately, regardless of whether there are more targets to try. 
     80==== Defer the Decision ==== 
     82Set the ''cmd'' argument of the callback to ''PJSIP_REDIRECT_PENDING'' to tell the invite session that a decision cannot be made that this time (for example to ask for user approval), and the application will notify the invite session about the decision later. 
     84Once the application decides what to do with the redirection, it '''MUST''' call {{{pjsip_inv_process_redirect()}}} function to notify the session about this. It may accept or reject the target, or stop the redirection altogether by setting the appropriate value to the ''cmd'' argument. It must not set ''PJSIP_REDIRECT_PENDING'' to this argument. 
     86Failure to call {{{pjsip_inv_process_redirect()}}} will cause the invite session to be kept alive indefinitely until the library is shutdown. 
     89=== PJSUA-LIB === 
     91Similar callback and function were added to PJSUA-LIB: 
     93 {{{ 
     94void (*on_call_redirected)(pjsua_call_id call_id, const pjsip_uri *target, 
     95                           pjsip_redirect_op *cmd, const pjsip_event *e); 
     97PJ_DECL(pj_status_t) pjsua_call_process_redirect(pjsua_call_id call_id, 
     98                                                 pjsip_redirect_op cmd); 
     99 }}} 
     101Please see the PJSIP section above on how to use this feature. 
     104=== pjsua === 
     106The following additions were made to pjsua: 
     108 - new command line argument "{{{--accept-redirect=N}}}", with valid values for N:  
     109    - 0: reject/stop,  
     110    - 1: follow automatically (default),  
     111    - 2: ask 
     112 - the default behavior is to follow redirection automatically 
     113 - when {{{--accept-redirect}}} is set to 2 (ask), user can enter 'Ra', 'Rr', or 'Rd' to accept, reject, or stop/disconnect the redirection. 
     116== Open Issues == 
     118=== 3xx Response after 183 === 
     120When 3xx response is received after 183 with SDP response is received, the invite session will treat the SDP answer in the ''subsequent'' INVITE as an offer rather than answer. This is because the SDP has been negotiated in the previous INVITE offer/answer. 
     122While it is uncommon to send 183 before 3xx, this is a bug. 
     124=== Library shutdown with a pending redirection causes assertion failure === 
     126Assertion will be triggered in the invite session when the library is shutdown while the invite session is still waiting for {{{pjsip_inv_process_redirect}}} function to be called. 
     128While this is caused by application not following the requirement to call {{{pjsip_inv_process_redirect()}}}, nevertheless the library should be robust enough to handle this, so this will be fixed.