Ignore:
Timestamp:
Feb 21, 2008 7:28:21 PM (17 years ago)
Author:
bennylp
Message:

Ticket #488: When outgoing request within dialog is responded with 481 or 408, should send BYE after terminating dialog (thanks Philippe Leuba)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip/src/pjsip-ua/sip_inv.c

    r1733 r1814  
    28842884 
    28852885/* 
     2886 * Handle 408, 481, or any other responses that terminates dialog. 
     2887 */ 
     2888static pj_bool_t handle_408_481_response(pjsip_inv_session *inv,  
     2889                                         pjsip_event *e) 
     2890{ 
     2891    /* RFC 3261 Section 12.2.1.2: 
     2892     *  If the response for a request within a dialog is a 481 
     2893     *  (Call/Transaction Does Not Exist) or a 408 (Request Timeout), the UAC 
     2894     *  SHOULD terminate the dialog.  A UAC SHOULD also terminate a dialog if 
     2895     *  no response at all is received for the request (the client 
     2896     *  transaction would inform the TU about the timeout.) 
     2897     *  
     2898     *  For INVITE initiated dialogs, terminating the dialog consists of 
     2899     *  sending a BYE. 
     2900     * 
     2901     * Note: 
     2902     *  according to X, this should terminate dialog usage only, not the  
     2903     *  dialog. 
     2904     */ 
     2905    pjsip_transaction *tsx = e->body.tsx_state.tsx; 
     2906 
     2907    pj_assert(tsx->role == PJSIP_UAC_ROLE); 
     2908 
     2909    /* Note that 481 response to CANCEL does not terminate dialog usage, 
     2910     * but only the transaction. 
     2911     */ 
     2912    if ((tsx->status_code == PJSIP_SC_CALL_TSX_DOES_NOT_EXIST && 
     2913            tsx->method.id != PJSIP_CANCEL_METHOD) || 
     2914        tsx->status_code == PJSIP_SC_REQUEST_TIMEOUT || 
     2915        tsx->status_code == PJSIP_SC_TSX_TIMEOUT || 
     2916        tsx->status_code == PJSIP_SC_TSX_TRANSPORT_ERROR) 
     2917    { 
     2918        pjsip_tx_data *bye; 
     2919        pj_status_t status; 
     2920 
     2921        inv_set_cause(inv, tsx->status_code, &tsx->status_text); 
     2922        inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 
     2923 
     2924        /* Send BYE */ 
     2925        status = pjsip_dlg_create_request(inv->dlg, pjsip_get_bye_method(),  
     2926                                          -1, &bye); 
     2927        if (status == PJ_SUCCESS) { 
     2928            pjsip_inv_send_msg(inv, bye); 
     2929        } 
     2930 
     2931        return PJ_TRUE; /* Handled */ 
     2932 
     2933    } else { 
     2934        return PJ_FALSE; /* Unhandled */ 
     2935    } 
     2936} 
     2937 
     2938 
     2939/* 
    28862940 * State CONNECTING is after 2xx response to INVITE is sent/received. 
    28872941 */ 
     
    29943048         * Handle response to outgoing UPDATE request. 
    29953049         */ 
    2996         inv_handle_update_response(inv, e); 
     3050        if (handle_408_481_response(inv, e) == PJ_FALSE) 
     3051            inv_handle_update_response(inv, e); 
    29973052 
    29983053    } else if (tsx->role == PJSIP_ROLE_UAS && 
     
    30063061 
    30073062    } else if (tsx->role == PJSIP_ROLE_UAC) { 
    3008         /* 
    3009          * Handle case when outgoing request is answered with 481 (Call/ 
    3010          * Transaction Does Not Exist), 408, or when it's timed out. In these 
    3011          * cases, disconnect session (i.e. dialog usage only). 
    3012          * Note that 481 response to CANCEL does not terminate dialog usage, 
    3013          * but only the transaction. 
    3014          */ 
    3015         if ((tsx->status_code == PJSIP_SC_CALL_TSX_DOES_NOT_EXIST && 
    3016                 tsx->method.id != PJSIP_CANCEL_METHOD) || 
    3017             tsx->status_code == PJSIP_SC_REQUEST_TIMEOUT || 
    3018             tsx->status_code == PJSIP_SC_TSX_TIMEOUT || 
    3019             tsx->status_code == PJSIP_SC_TSX_TRANSPORT_ERROR) 
    3020         { 
    3021             inv_set_cause(inv, tsx->status_code, &tsx->status_text); 
    3022             inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 
    3023         } 
     3063         
     3064        handle_408_481_response(inv, e); 
    30243065    } 
    30253066 
     
    32503291            inv_send_ack(inv, e); 
    32513292 
     3293        } else if (handle_408_481_response(inv, e)) { 
     3294 
     3295            /* Handle response that terminates dialog */ 
     3296            /* Nothing to do (already handled) */ 
     3297 
    32523298        } else if (tsx->state == PJSIP_TSX_STATE_COMPLETED && 
    32533299                   (tsx->status_code==401 || tsx->status_code==407)) 
     
    32673313            status = pjsip_inv_send_msg( inv, tdata); 
    32683314 
    3269         } else if (tsx->status_code==PJSIP_SC_CALL_TSX_DOES_NOT_EXIST || 
    3270                    tsx->status_code==PJSIP_SC_REQUEST_TIMEOUT || 
    3271                    tsx->status_code >= 700) 
    3272         { 
    3273             /* 
    3274              * Handle responses that terminates dialog. 
    3275              */ 
    3276             inv_set_cause(inv, tsx->status_code, &tsx->status_text); 
    3277             inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 
    3278  
    32793315        } else if (tsx->status_code >= 300 && tsx->status_code < 700) { 
    32803316 
     
    33053341         * Handle response to outgoing UPDATE request. 
    33063342         */ 
    3307         inv_handle_update_response(inv, e); 
     3343        if (handle_408_481_response(inv, e) == PJ_FALSE) 
     3344            inv_handle_update_response(inv, e); 
    33083345 
    33093346    } else if (tsx->role == PJSIP_ROLE_UAS && 
     
    33183355    } else if (tsx->role == PJSIP_ROLE_UAC) { 
    33193356        /* 
    3320          * Handle case when outgoing request is answered with 481 (Call/ 
    3321          * Transaction Does Not Exist), 408, or when it's timed out. In these 
    3322          * cases, disconnect session (i.e. dialog usage only). 
    3323          * Note that 481 response to CANCEL does not terminate dialog usage, 
    3324          * but only the transaction. 
    3325          */ 
    3326         if ((tsx->status_code == PJSIP_SC_CALL_TSX_DOES_NOT_EXIST && 
    3327                 tsx->method.id != PJSIP_CANCEL_METHOD) || 
    3328             tsx->status_code == PJSIP_SC_REQUEST_TIMEOUT || 
    3329             tsx->status_code == PJSIP_SC_TSX_TIMEOUT || 
    3330             tsx->status_code == PJSIP_SC_TSX_TRANSPORT_ERROR) 
    3331         { 
    3332             inv_set_cause(inv, tsx->status_code, &tsx->status_text); 
    3333             inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 
    3334         } 
     3357         * Handle 408/481 response 
     3358         */ 
     3359        handle_408_481_response(inv, e); 
    33353360    } 
    33363361 
Note: See TracChangeset for help on using the changeset viewer.