- Timestamp:
- Jun 25, 2008 10:15:01 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/src/pjsip-ua/sip_inv.c
r2039 r2049 2361 2361 2362 2362 } else { 2363 /* Re-send BYE. */2363 /* Re-send request. */ 2364 2364 status = pjsip_inv_send_msg(inv, tdata); 2365 2365 } … … 2517 2517 } 2518 2518 } 2519 2520 /* 2521 * Generic UAC transaction handler: 2522 * - resend request on 401 or 407 response. 2523 * - terminate dialog on 408 and 481 response. 2524 */ 2525 static pj_bool_t handle_uac_tsx_response(pjsip_inv_session *inv, 2526 pjsip_event *e) 2527 { 2528 /* RFC 3261 Section 12.2.1.2: 2529 * If the response for a request within a dialog is a 481 2530 * (Call/Transaction Does Not Exist) or a 408 (Request Timeout), the UAC 2531 * SHOULD terminate the dialog. A UAC SHOULD also terminate a dialog if 2532 * no response at all is received for the request (the client 2533 * transaction would inform the TU about the timeout.) 2534 * 2535 * For INVITE initiated dialogs, terminating the dialog consists of 2536 * sending a BYE. 2537 * 2538 * Note: 2539 * according to X, this should terminate dialog usage only, not the 2540 * dialog. 2541 */ 2542 pjsip_transaction *tsx = e->body.tsx_state.tsx; 2543 2544 pj_assert(tsx->role == PJSIP_UAC_ROLE); 2545 2546 /* Note that 481 response to CANCEL does not terminate dialog usage, 2547 * but only the transaction. 2548 */ 2549 if ((tsx->status_code == PJSIP_SC_CALL_TSX_DOES_NOT_EXIST && 2550 tsx->method.id != PJSIP_CANCEL_METHOD) || 2551 tsx->status_code == PJSIP_SC_REQUEST_TIMEOUT || 2552 tsx->status_code == PJSIP_SC_TSX_TIMEOUT || 2553 tsx->status_code == PJSIP_SC_TSX_TRANSPORT_ERROR) 2554 { 2555 pjsip_tx_data *bye; 2556 pj_status_t status; 2557 2558 inv_set_cause(inv, tsx->status_code, &tsx->status_text); 2559 inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 2560 2561 /* Send BYE */ 2562 status = pjsip_dlg_create_request(inv->dlg, pjsip_get_bye_method(), 2563 -1, &bye); 2564 if (status == PJ_SUCCESS) { 2565 pjsip_inv_send_msg(inv, bye); 2566 } 2567 2568 return PJ_TRUE; /* Handled */ 2569 2570 } 2571 /* Handle 401/407 challenge. */ 2572 else if (tsx->state == PJSIP_TSX_STATE_COMPLETED && 2573 (tsx->status_code == PJSIP_SC_UNAUTHORIZED || 2574 tsx->status_code == PJSIP_SC_PROXY_AUTHENTICATION_REQUIRED)) 2575 { 2576 2577 pjsip_tx_data *tdata; 2578 pj_status_t status; 2579 2580 status = pjsip_auth_clt_reinit_req( &inv->dlg->auth_sess, 2581 e->body.tsx_state.src.rdata, 2582 tsx->last_tx, &tdata); 2583 2584 if (status != PJ_SUCCESS) { 2585 /* Does not have proper credentials. End the session. */ 2586 inv_set_cause(inv, PJSIP_SC_OK, NULL); 2587 inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 2588 2589 } else { 2590 /* Re-send request. */ 2591 if (tsx->method.id == PJSIP_INVITE_METHOD) 2592 inv->invite_tsx = NULL; 2593 2594 status = pjsip_inv_send_msg(inv, tdata); 2595 } 2596 2597 return PJ_TRUE; /* Handled */ 2598 2599 } else { 2600 return PJ_FALSE; /* Unhandled */ 2601 } 2602 } 2603 2519 2604 2520 2605 /* … … 2874 2959 2875 2960 } else if (tsx->role == PJSIP_ROLE_UAC) { 2876 /* 2877 * Handle case when outgoing request is answered with 481 (Call/ 2878 * Transaction Does Not Exist), 408, or when it's timed out. In these 2879 * cases, disconnect session (i.e. dialog usage only). 2880 * Note that 481 response to CANCEL does not terminate dialog usage, 2881 * but only the transaction. 2882 */ 2883 if ((tsx->status_code == PJSIP_SC_CALL_TSX_DOES_NOT_EXIST && 2884 tsx->method.id != PJSIP_CANCEL_METHOD) || 2885 tsx->status_code == PJSIP_SC_REQUEST_TIMEOUT || 2886 tsx->status_code == PJSIP_SC_TSX_TIMEOUT || 2887 tsx->status_code == PJSIP_SC_TSX_TRANSPORT_ERROR) 2888 { 2889 inv_set_cause(inv, tsx->status_code, &tsx->status_text); 2890 inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 2891 } 2892 } 2893 } 2894 2895 /* 2896 * Handle 408, 481, or any other responses that terminates dialog. 2897 */ 2898 static pj_bool_t handle_408_481_response(pjsip_inv_session *inv, 2899 pjsip_event *e) 2900 { 2901 /* RFC 3261 Section 12.2.1.2: 2902 * If the response for a request within a dialog is a 481 2903 * (Call/Transaction Does Not Exist) or a 408 (Request Timeout), the UAC 2904 * SHOULD terminate the dialog. A UAC SHOULD also terminate a dialog if 2905 * no response at all is received for the request (the client 2906 * transaction would inform the TU about the timeout.) 2907 * 2908 * For INVITE initiated dialogs, terminating the dialog consists of 2909 * sending a BYE. 2910 * 2911 * Note: 2912 * according to X, this should terminate dialog usage only, not the 2913 * dialog. 2914 */ 2915 pjsip_transaction *tsx = e->body.tsx_state.tsx; 2916 2917 pj_assert(tsx->role == PJSIP_UAC_ROLE); 2918 2919 /* Note that 481 response to CANCEL does not terminate dialog usage, 2920 * but only the transaction. 2921 */ 2922 if ((tsx->status_code == PJSIP_SC_CALL_TSX_DOES_NOT_EXIST && 2923 tsx->method.id != PJSIP_CANCEL_METHOD) || 2924 tsx->status_code == PJSIP_SC_REQUEST_TIMEOUT || 2925 tsx->status_code == PJSIP_SC_TSX_TIMEOUT || 2926 tsx->status_code == PJSIP_SC_TSX_TRANSPORT_ERROR) 2927 { 2928 pjsip_tx_data *bye; 2929 pj_status_t status; 2930 2931 inv_set_cause(inv, tsx->status_code, &tsx->status_text); 2932 inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 2933 2934 /* Send BYE */ 2935 status = pjsip_dlg_create_request(inv->dlg, pjsip_get_bye_method(), 2936 -1, &bye); 2937 if (status == PJ_SUCCESS) { 2938 pjsip_inv_send_msg(inv, bye); 2939 } 2940 2941 return PJ_TRUE; /* Handled */ 2942 2943 } else { 2944 return PJ_FALSE; /* Unhandled */ 2945 } 2946 } 2947 2961 2962 /* Generic handling for UAC tsx completion */ 2963 handle_uac_tsx_response(inv, e); 2964 } 2965 } 2948 2966 2949 2967 /* … … 3058 3076 * Handle response to outgoing UPDATE request. 3059 3077 */ 3060 if (handle_ 408_481_response(inv, e) == PJ_FALSE)3078 if (handle_uac_tsx_response(inv, e) == PJ_FALSE) 3061 3079 inv_handle_update_response(inv, e); 3062 3080 … … 3072 3090 } else if (tsx->role == PJSIP_ROLE_UAC) { 3073 3091 3074 handle_408_481_response(inv, e); 3092 /* Generic handling for UAC tsx completion */ 3093 handle_uac_tsx_response(inv, e); 3075 3094 } 3076 3095 … … 3309 3328 inv_send_ack(inv, e); 3310 3329 3311 } else if (handle_ 408_481_response(inv, e)) {3330 } else if (handle_uac_tsx_response(inv, e)) { 3312 3331 3313 3332 /* Handle response that terminates dialog */ 3314 3333 /* Nothing to do (already handled) */ 3315 3316 } else if (tsx->state == PJSIP_TSX_STATE_COMPLETED &&3317 (tsx->status_code==401 || tsx->status_code==407))3318 {3319 pjsip_tx_data *tdata;3320 pj_status_t status;3321 3322 /* Handle authentication challenge. */3323 status = pjsip_auth_clt_reinit_req( &dlg->auth_sess,3324 e->body.tsx_state.src.rdata,3325 tsx->last_tx,3326 &tdata);3327 if (status != PJ_SUCCESS)3328 return;3329 3330 /* Retry INVITE request */3331 inv->invite_tsx = NULL;3332 3333 /* Send re-INVITE */3334 status = pjsip_inv_send_msg( inv, tdata);3335 3334 3336 3335 } else if (tsx->status_code >= 300 && tsx->status_code < 700) { … … 3362 3361 * Handle response to outgoing UPDATE request. 3363 3362 */ 3364 if (handle_ 408_481_response(inv, e) == PJ_FALSE)3363 if (handle_uac_tsx_response(inv, e) == PJ_FALSE) 3365 3364 inv_handle_update_response(inv, e); 3366 3365 … … 3376 3375 } else if (tsx->role == PJSIP_ROLE_UAC) { 3377 3376 /* 3378 * Handle 40 8/481 response3377 * Handle 401/407/408/481 response 3379 3378 */ 3380 handle_ 408_481_response(inv, e);3379 handle_uac_tsx_response(inv, e); 3381 3380 } 3382 3381
Note: See TracChangeset
for help on using the changeset viewer.