Ignore:
Timestamp:
Aug 4, 2008 3:01:38 PM (16 years ago)
Author:
nanang
Message:

Ticket #563: Updated SDP offer/answer related to call hold scenario to conform to RFC 3264 section 8.4 (before: 'a=inactive' and 'c=0.0.0.0', now: 'a=sendonly' and muted ports).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c

    r2152 r2191  
    6767 
    6868 
    69  
    70 /* Create inactive SDP for call hold. */ 
    71 static pj_status_t create_inactive_sdp(pjsua_call *call, 
    72                                        pjmedia_sdp_session **p_answer); 
     69/* Create SDP for call hold. */ 
     70static pj_status_t create_sdp_of_call_hold(pjsua_call *call, 
     71                                           pjmedia_sdp_session **p_answer); 
    7372 
    7473/* Update SDP version in the offer */ 
     
    118117    call->rem_nat_type = PJ_STUN_NAT_TYPE_UNKNOWN; 
    119118    call->rem_srtp_use = PJMEDIA_SRTP_DISABLED; 
     119    call->local_hold = PJ_FALSE; 
    120120} 
    121121 
     
    14271427    } 
    14281428 
    1429     status = create_inactive_sdp(call, &sdp); 
     1429    status = create_sdp_of_call_hold(call, &sdp); 
    14301430    if (status != PJ_SUCCESS) { 
    14311431        pjsip_dlg_dec_lock(dlg); 
     
    14531453        return status; 
    14541454    } 
     1455 
     1456    /* Set flag that local put the call on hold */ 
     1457    call->local_hold = PJ_TRUE; 
    14551458 
    14561459    pjsip_dlg_dec_lock(dlg); 
     
    14881491 
    14891492    /* Create SDP */ 
    1490     PJ_UNUSED_ARG(unhold); 
    1491     PJ_TODO(create_active_inactive_sdp_based_on_unhold_arg); 
    1492     status = pjsua_media_channel_create_sdp(call->index, call->inv->pool,  
    1493                                             NULL, &sdp, NULL); 
     1493    if (call->local_hold && !unhold) { 
     1494        status = create_sdp_of_call_hold(call, &sdp); 
     1495    } else { 
     1496        status = pjsua_media_channel_create_sdp(call->index, call->inv->pool,  
     1497                                                NULL, &sdp, NULL); 
     1498        call->local_hold = PJ_FALSE; 
     1499    } 
    14941500    if (status != PJ_SUCCESS) { 
    14951501        pjsua_perror(THIS_FILE, "Unable to get SDP from media endpoint",  
     
    15741580    status = pjsip_inv_send_msg( call->inv, tdata); 
    15751581    if (status != PJ_SUCCESS) { 
    1576         pjsua_perror(THIS_FILE, "Unable to send UPDAT Erequest", status); 
     1582        pjsua_perror(THIS_FILE, "Unable to send UPDATE request", status); 
    15771583        pjsip_dlg_dec_lock(dlg); 
    15781584        return status; 
    15791585    } 
     1586 
     1587    call->local_hold = PJ_FALSE; 
    15801588 
    15811589    pjsip_dlg_dec_lock(dlg); 
     
    30133021 
    30143022 
    3015 /* 
    3016  * Create inactive SDP for call hold. 
    3017  */ 
    3018 static pj_status_t create_inactive_sdp(pjsua_call *call, 
    3019                                        pjmedia_sdp_session **p_answer) 
     3023/* Create SDP for call hold. */ 
     3024static pj_status_t create_sdp_of_call_hold(pjsua_call *call, 
     3025                                           pjmedia_sdp_session **p_answer) 
    30203026{ 
    30213027    pj_status_t status; 
    30223028    pj_pool_t *pool; 
    3023     pjmedia_sdp_conn *conn; 
    3024     pjmedia_sdp_attr *attr; 
    3025     pjmedia_transport_info tp_info; 
    30263029    pjmedia_sdp_session *sdp; 
    30273030 
     
    30293032    pool = call->inv->pool; 
    30303033 
    3031     /* Get media socket info */ 
    3032     pjmedia_transport_info_init(&tp_info); 
    3033     pjmedia_transport_get_info(call->med_tp, &tp_info); 
    3034  
    30353034    /* Create new offer */ 
    3036     status = pjmedia_endpt_create_sdp(pjsua_var.med_endpt, pool, 1, 
    3037                                       &tp_info.sock_info, &sdp); 
     3035    status = pjsua_media_channel_create_sdp(call->index, pool, NULL, &sdp,  
     3036                                            NULL); 
    30383037    if (status != PJ_SUCCESS) { 
    30393038        pjsua_perror(THIS_FILE, "Unable to create local SDP", status); 
     
    30413040    } 
    30423041 
    3043     /* Get SDP media connection line */ 
    3044     conn = sdp->media[0]->conn; 
    3045     if (!conn) 
    3046         conn = sdp->conn; 
    3047  
    3048     /* Modify address */ 
    3049     conn->addr = pj_str("0.0.0.0"); 
    3050  
    3051     /* Remove existing directions attributes */ 
    3052     pjmedia_sdp_media_remove_all_attr(sdp->media[0], "sendrecv"); 
    3053     pjmedia_sdp_media_remove_all_attr(sdp->media[0], "sendonly"); 
    3054     pjmedia_sdp_media_remove_all_attr(sdp->media[0], "recvonly"); 
    3055     pjmedia_sdp_media_remove_all_attr(sdp->media[0], "inactive"); 
    3056  
    3057     /* Add inactive attribute */ 
    3058     attr = pjmedia_sdp_attr_create(pool, "inactive", NULL); 
    3059     pjmedia_sdp_media_add_attr(sdp->media[0], attr); 
     3042    /* Call-hold is done by set the media direction to 'sendonly'  
     3043     * (PJMEDIA_DIR_ENCODING), except when current media direction is  
     3044     * 'inactive' (PJMEDIA_DIR_NONE). 
     3045     * (See RFC 3264 Section 8.4 and RFC 4317 Section 3.1) 
     3046     */ 
     3047    if (call->media_dir != PJMEDIA_DIR_ENCODING) { 
     3048        pjmedia_sdp_attr *attr; 
     3049 
     3050        /* Remove existing directions attributes */ 
     3051        pjmedia_sdp_media_remove_all_attr(sdp->media[0], "sendrecv"); 
     3052        pjmedia_sdp_media_remove_all_attr(sdp->media[0], "sendonly"); 
     3053        pjmedia_sdp_media_remove_all_attr(sdp->media[0], "recvonly"); 
     3054        pjmedia_sdp_media_remove_all_attr(sdp->media[0], "inactive"); 
     3055 
     3056        if (call->media_dir == PJMEDIA_DIR_ENCODING_DECODING) { 
     3057            /* Add sendonly attribute */ 
     3058            attr = pjmedia_sdp_attr_create(pool, "sendonly", NULL); 
     3059            pjmedia_sdp_media_add_attr(sdp->media[0], attr); 
     3060        } else { 
     3061            /* Add inactive attribute */ 
     3062            attr = pjmedia_sdp_attr_create(pool, "inactive", NULL); 
     3063            pjmedia_sdp_media_add_attr(sdp->media[0], attr); 
     3064        } 
     3065    } 
    30603066 
    30613067    *p_answer = sdp; 
     
    30633069    return status; 
    30643070} 
    3065  
    30663071 
    30673072/* 
     
    30713076                                   const pjmedia_sdp_session *offer) 
    30723077{ 
    3073     const char *remote_state; 
    30743078    pjsua_call *call; 
    30753079    pjmedia_sdp_conn *conn; 
    30763080    pjmedia_sdp_session *answer; 
    3077     pj_bool_t is_remote_active; 
    30783081    pj_status_t status; 
    30793082 
     
    30813084 
    30823085    call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id]; 
    3083  
    3084     /* 
    3085      * See if remote is offering active media (i.e. not on-hold) 
    3086      */ 
    3087     is_remote_active = PJ_TRUE; 
    30883086 
    30893087    conn = offer->media[0]->conn; 
     
    30913089        conn = offer->conn; 
    30923090 
     3091    /* Supply candidate answer */ 
     3092    PJ_LOG(4,(THIS_FILE, "Call %d: received updated media offer", 
     3093              call->index)); 
     3094 
     3095    status = pjsua_media_channel_create_sdp(call->index, call->inv->pool,  
     3096                                            offer, &answer, NULL); 
     3097    if (status != PJ_SUCCESS) { 
     3098        pjsua_perror(THIS_FILE, "Unable to create local SDP", status); 
     3099        PJSUA_UNLOCK(); 
     3100        return; 
     3101    } 
     3102 
     3103    /* Check if offer's conn address is zero */ 
    30933104    if (pj_strcmp2(&conn->addr, "0.0.0.0")==0 || 
    30943105        pj_strcmp2(&conn->addr, "0")==0) 
    30953106    { 
    3096         is_remote_active = PJ_FALSE; 
    3097  
    3098     }  
    3099     else if (pjmedia_sdp_media_find_attr2(offer->media[0], "inactive", NULL) || 
    3100              pjmedia_sdp_media_find_attr2(offer->media[0], "sendonly", NULL)) 
    3101     { 
    3102         is_remote_active = PJ_FALSE; 
    3103     } 
    3104  
    3105     remote_state = (is_remote_active ? "active" : "inactive"); 
    3106  
    3107     /* Supply candidate answer */ 
    3108     if (call->media_st == PJSUA_CALL_MEDIA_LOCAL_HOLD || !is_remote_active) { 
    3109         PJ_LOG(4,(THIS_FILE,  
    3110                   "Call %d: RX new media offer, creating inactive SDP " 
    3111                   "(media in offer is %s)", call->index, remote_state)); 
    3112         status = create_inactive_sdp( call, &answer ); 
    3113     } else { 
    3114         PJ_LOG(4,(THIS_FILE, "Call %d: received updated media offer", 
    3115                   call->index)); 
    3116  
    3117         status = pjsua_media_channel_create_sdp(call->index, call->inv->pool,  
    3118                                                 offer, &answer, NULL); 
    3119     } 
    3120  
    3121     if (status != PJ_SUCCESS) { 
    3122         pjsua_perror(THIS_FILE, "Unable to create local SDP", status); 
    3123         PJSUA_UNLOCK(); 
    3124         return; 
     3107        /* Modify address */ 
     3108        answer->conn->addr = pj_str("0.0.0.0"); 
     3109    } 
     3110 
     3111    /* Check if call is on-hold */ 
     3112    if (call->local_hold) { 
     3113        pjmedia_sdp_attr *attr; 
     3114 
     3115        /* Remove existing directions attributes */ 
     3116        pjmedia_sdp_media_remove_all_attr(answer->media[0], "sendrecv"); 
     3117        pjmedia_sdp_media_remove_all_attr(answer->media[0], "sendonly"); 
     3118        pjmedia_sdp_media_remove_all_attr(answer->media[0], "recvonly"); 
     3119        pjmedia_sdp_media_remove_all_attr(answer->media[0], "inactive"); 
     3120 
     3121        /* Keep call on-hold by setting 'sendonly' attribute. 
     3122         * (See RFC 3264 Section 8.4 and RFC 4317 Section 3.1) 
     3123         */ 
     3124        attr = pjmedia_sdp_attr_create(call->inv->pool, "sendonly", NULL); 
     3125        pjmedia_sdp_media_add_attr(answer->media[0], attr); 
    31253126    } 
    31263127 
     
    31503151 
    31513152    /* See if we've put call on hold. */ 
    3152     if (call->media_st == PJSUA_CALL_MEDIA_LOCAL_HOLD) { 
     3153    if (call->local_hold) { 
    31533154        PJ_LOG(4,(THIS_FILE,  
    3154                   "Call %d: call is on-hold locally, creating inactive SDP ", 
     3155                  "Call %d: call is on-hold locally, creating call-hold SDP ", 
    31553156                  call->index)); 
    3156         status = create_inactive_sdp( call, offer ); 
     3157        status = create_sdp_of_call_hold( call, offer ); 
    31573158    } else { 
    31583159        PJ_LOG(4,(THIS_FILE, "Call %d: asked to send a new offer", 
Note: See TracChangeset for help on using the changeset viewer.