Changeset 3560 for pjproject


Ignore:
Timestamp:
May 10, 2011 5:42:28 AM (14 years ago)
Author:
nanang
Message:

Fix #1237, #1238, #1241:

  • Fixed handling remote re-offer, where SDP media line may be added or removed.
  • Fixed bug in receiving remote offer (initial or subsequent), media channel create sdp must consider acc->cfg.max_audio_cnt setting.
  • Fixed bug media transport is not closed after call disconnected.
  • Fixed assertion in lock_codec after receiving initial answer but no acceptable media (in pjsua level, e.g: SRTP nego failed), now the call will be terminated.
Location:
pjproject/branches/projects/2.0-dev/pjsip
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • pjproject/branches/projects/2.0-dev/pjsip/include/pjsua-lib/pjsua_internal.h

    r3471 r3560  
    4040 
    4141    /** Running (media_start() has been called) */ 
    42     PJSUA_MED_TP_RUNNING 
     42    PJSUA_MED_TP_RUNNING, 
     43 
     44    /** Disabled (transport is initialized, but media is being disabled) */ 
     45    PJSUA_MED_TP_DISABLED 
    4346 
    4447} pjsua_med_tp_st; 
  • pjproject/branches/projects/2.0-dev/pjsip/src/pjsua-lib/pjsua_media.c

    r3521 r3560  
    13711371            return status; 
    13721372        } 
     1373         
     1374        call_med->tp_st = PJSUA_MED_TP_IDLE; 
     1375    } else if (call_med->tp_st == PJSUA_MED_TP_DISABLED) { 
     1376        /* Media is being reenabled. */ 
     1377        call_med->tp_st = PJSUA_MED_TP_INIT; 
    13731378    } 
    13741379 
     
    13931398        /* Always create SRTP adapter */ 
    13941399        pjmedia_srtp_setting_default(&srtp_opt); 
    1395         srtp_opt.close_member_tp = PJ_FALSE; 
     1400        srtp_opt.close_member_tp = PJ_TRUE; 
    13961401        /* If media session has been ever established, let's use remote's 
    13971402         * preference in SRTP usage policy, especially when it is stricter. 
     
    14511456    PJ_UNUSED_ARG(role); 
    14521457 
     1458    /* 
     1459     * Note: this function may be called when the media already exists 
     1460     * (e.g. in reinvites, updates, etc). 
     1461     */ 
     1462 
    14531463    if (pjsua_get_state() != PJSUA_STATE_RUNNING) 
    14541464        return PJ_EBUSY; 
     
    14681478        sort_media(rem_sdp, &STR_AUDIO, acc->cfg.use_srtp, 
    14691479                   maudidx, &maudcnt); 
     1480        if (maudcnt > acc->cfg.max_audio_cnt) 
     1481            maudcnt = acc->cfg.max_audio_cnt; 
    14701482 
    14711483        if (maudcnt==0) { 
     
    14781490        sort_media(rem_sdp, &STR_VIDEO, acc->cfg.use_srtp, 
    14791491                   mvididx, &mvidcnt); 
    1480         mvidcnt = (mvidcnt < acc->cfg.max_video_cnt) ? 
    1481                         mvidcnt : acc->cfg.max_video_cnt; 
     1492        if (mvidcnt > acc->cfg.max_video_cnt) 
     1493            mvidcnt = acc->cfg.max_video_cnt; 
     1494 
     1495        /* Update media count only when remote add any media, this media count 
     1496         * must never decrease. 
     1497         */ 
     1498        if (call->med_cnt < rem_sdp->media_count) 
     1499            call->med_cnt = PJ_MIN(rem_sdp->media_count, PJSUA_MAX_CALL_MEDIA); 
    14821500 
    14831501    } else { 
     
    14911509            media_types[maudcnt + mi] = PJMEDIA_TYPE_VIDEO; 
    14921510        } 
    1493     } 
    1494  
    1495     call->med_cnt = maudcnt + mvidcnt; 
     1511         
     1512        call->med_cnt = maudcnt + mvidcnt; 
     1513    } 
    14961514 
    14971515    if (call->med_cnt == 0) { 
     
    15091527 
    15101528        if (rem_sdp) { 
    1511             if (!pj_stricmp(&rem_sdp->media[mi]->desc.media, &STR_AUDIO)) { 
     1529            if (mi >= rem_sdp->media_count) { 
     1530                /* Media has been removed in remote re-offer */ 
     1531                media_type = call_med->type; 
     1532            } else if (!pj_stricmp(&rem_sdp->media[mi]->desc.media, &STR_AUDIO)) { 
    15121533                media_type = PJMEDIA_TYPE_AUDIO; 
    15131534                if (pj_memchr(maudidx, mi, maudcnt * sizeof(maudidx[0]))) { 
     
    15361557            } 
    15371558        } else { 
    1538             /* By convention, the media is inactive if transport is NULL */ 
     1559            /* By convention, the media is disabled if transport is NULL  
     1560             * or transport state is PJSUA_MED_TP_DISABLED. 
     1561             */ 
    15391562            if (call_med->tp) { 
    1540                 pjmedia_transport_close(call_med->tp); 
    1541                 call_med->tp = NULL; 
     1563                // Don't close transport here, as SDP negotiation has not been 
     1564                // done and stream may be still active. 
     1565                //pjmedia_transport_close(call_med->tp); 
     1566                //call_med->tp = NULL; 
     1567                pj_assert(call_med->tp_st == PJSUA_MED_TP_INIT ||  
     1568                          call_med->tp_st == PJSUA_MED_TP_RUNNING); 
     1569                call_med->tp_st = PJSUA_MED_TP_DISABLED; 
    15421570            } 
     1571 
     1572            /* Put media type just for info */ 
     1573            call_med->type = media_type; 
    15431574        } 
    15441575    } 
     
    15531584        pjsua_call_media *call_med = &call->media[mi]; 
    15541585 
    1555         /* Note: tp may be NULL if this media line is inactive */ 
    1556         if (call_med->tp) { 
     1586        /* Note: tp may be NULL if this media line is disabled */ 
     1587        if (call_med->tp && call_med->tp_st == PJSUA_MED_TP_IDLE) { 
    15571588            status = pjmedia_transport_media_create(call_med->tp, 
    15581589                                                    tmp_pool, 0, 
     
    15771608                                           int *sip_err_code) 
    15781609{ 
    1579     const pj_str_t STR_AUDIO = { "audio", 5 }; 
    15801610    enum { MAX_MEDIA = PJSUA_MAX_CALL_MEDIA }; 
    15811611    pjmedia_sdp_session *sdp; 
    15821612    pj_sockaddr origin; 
    15831613    pjsua_call *call = &pjsua_var.calls[call_id]; 
    1584     pjsua_acc *acc = &pjsua_var.acc[call->acc_id]; 
    15851614    pjmedia_sdp_neg_state sdp_neg_state = PJMEDIA_SDP_NEG_STATE_NULL; 
    15861615    unsigned mi; 
     
    15911620 
    15921621    if (rem_sdp) { 
     1622        /* If this is a re-offer, let's re-initialize media as remote may 
     1623         * add or remove media 
     1624         */ 
     1625        if (call->inv && call->inv->state == PJSIP_INV_STATE_CONFIRMED) { 
     1626            status = pjsua_media_channel_init(call_id, PJSIP_ROLE_UAS, 
     1627                                              call->secure_level, pool, 
     1628                                              rem_sdp, sip_err_code); 
     1629            if (status != PJ_SUCCESS) 
     1630                return status; 
     1631        } 
     1632 
     1633#if 0 
     1634        pjsua_acc *acc = &pjsua_var.acc[call->acc_id]; 
    15931635        pj_uint8_t maudidx[PJSUA_MAX_CALL_MEDIA]; 
    15941636        unsigned maudcnt = PJ_ARRAY_SIZE(maudidx); 
     
    16051647 
    16061648        call->audio_idx = maudidx[0]; 
     1649#endif 
    16071650    } else { 
    16081651        /* Audio is first in our offer, by convention */ 
    1609         call->audio_idx = 0; 
    1610     } 
    1611  
     1652        // The audio_idx should not be changed here, as this function may be 
     1653        // called in generating re-offer and the current active audio index 
     1654        // can be anywhere. 
     1655        //call->audio_idx = 0; 
     1656    } 
     1657 
     1658#if 0 
     1659    // Since r3512, old-style hold should have got transport, created by  
     1660    // pjsua_media_channel_init() in initial offer/answer or remote reoffer. 
    16121661    /* Create media if it's not created. This could happen when call is 
    16131662     * currently on-hold (with the old style hold) 
     
    16211670            return status; 
    16221671    } 
     1672#endif 
    16231673 
    16241674    /* Get SDP negotiator state */ 
     
    16521702        pjmedia_transport_info tpinfo; 
    16531703 
    1654         if (call_med->tp == NULL) { 
     1704        if (rem_sdp && mi >= rem_sdp->media_count) { 
     1705            /* Remote might have removed some media lines. */ 
     1706            break; 
     1707        } 
     1708 
     1709        if (call_med->tp == NULL || call_med->tp_st == PJSUA_MED_TP_DISABLED) 
     1710        { 
    16551711            /* 
    1656              * This media is deactivated. Just create a valid SDP with zero 
     1712             * This media is disabled. Just create a valid SDP with zero 
    16571713             * port. 
    16581714             */ 
     
    19161972        } 
    19171973 
    1918         if (call_med->tp_orig && call_med->tp && 
    1919                 call_med->tp != call_med->tp_orig) 
    1920         { 
     1974        //if (call_med->tp_orig && call_med->tp && 
     1975        //      call_med->tp != call_med->tp_orig) 
     1976        //{ 
     1977        //    pjmedia_transport_close(call_med->tp); 
     1978        //    call_med->tp = call_med->tp_orig; 
     1979        //} 
     1980        if (call_med->tp) { 
    19211981            pjmedia_transport_close(call_med->tp); 
    1922             call_med->tp = call_med->tp_orig; 
     1982            call_med->tp = call_med->tp_orig = NULL; 
    19231983        } 
    19241984    } 
     
    24142474    pj_pool_t *tmp_pool = call->inv->pool_prov; 
    24152475    unsigned mi; 
     2476    pj_bool_t got_media = PJ_FALSE; 
    24162477    pj_status_t status = PJ_SUCCESS; 
    24172478 
     
    24292490        pjsua_call_media *call_med = &call->media[mi]; 
    24302491 
    2431         if (mi > local_sdp->media_count || 
    2432             mi > remote_sdp->media_count) 
     2492        if (mi >= local_sdp->media_count || 
     2493            mi >= remote_sdp->media_count) 
    24332494        { 
     2495            /* This may happen when remote removed any SDP media lines in 
     2496             * its re-offer. 
     2497             */ 
     2498            continue; 
     2499#if 0 
    24342500            /* Something is wrong */ 
    24352501            PJ_LOG(1,(THIS_FILE, "Error updating media for call %d: " 
    24362502                      "invalid media index %d in SDP", call_id, mi)); 
    24372503            return PJMEDIA_SDP_EINSDP; 
     2504#endif 
    24382505        } 
    24392506 
     
    24552522#endif 
    24562523        default: 
     2524            status = PJMEDIA_EINVALIMEDIATYPE; 
    24572525            break; 
    24582526        } 
    24592527 
    24602528        if (status != PJ_SUCCESS) { 
    2461             PJ_PERROR(1,(THIS_FILE, status, "Error updating media call%02:%d", 
     2529            PJ_PERROR(1,(THIS_FILE, status, "Error updating media call%02d:%d", 
    24622530                         call_id, mi)); 
    2463         } 
    2464     } 
    2465  
    2466     return PJ_SUCCESS; 
     2531        } else { 
     2532            got_media = PJ_TRUE; 
     2533        } 
     2534    } 
     2535 
     2536    return (got_media? PJ_SUCCESS : PJMEDIA_SDPNEG_ENOMEDIA); 
    24672537} 
    24682538 
Note: See TracChangeset for help on using the changeset viewer.