Ignore:
Timestamp:
May 7, 2008 3:30:34 PM (16 years ago)
Author:
nanang
Message:

Ticket #527: Commited ticket527.2.patch

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/src/pjmedia/sdp_neg.c

    r1810 r1950  
    225225                                    const pjmedia_sdp_session *local) 
    226226{ 
     227    pjmedia_sdp_session *new_offer; 
     228    pjmedia_sdp_session *old_offer; 
     229    char media_used[PJMEDIA_MAX_SDP_MEDIA]; 
     230    unsigned oi; /* old offer media index */ 
     231    pj_status_t status; 
     232 
    227233    /* Check arguments are valid. */ 
    228234    PJ_ASSERT_RETURN(pool && neg && local, PJ_EINVAL); 
     
    232238                     PJMEDIA_SDPNEG_EINSTATE); 
    233239 
     240    /* Validate the new offer */ 
     241    status = pjmedia_sdp_validate(local); 
     242    if (status != PJ_SUCCESS) 
     243        return status; 
     244 
    234245    /* Change state to STATE_LOCAL_OFFER */ 
    235246    neg->state = PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER; 
    236     neg->initial_sdp = pjmedia_sdp_session_clone(pool, local); 
    237     neg->neg_local_sdp = pjmedia_sdp_session_clone(pool, local); 
     247 
     248    /* Init vars */ 
     249    pj_bzero(media_used, sizeof(media_used)); 
     250    old_offer = neg->active_local_sdp; 
     251    new_offer = pjmedia_sdp_session_clone(pool, local); 
     252 
     253    /* RFC 3264 Section 8: When issuing an offer that modifies the session, 
     254     * the "o=" line of the new SDP MUST be identical to that in the 
     255     * previous SDP, except that the version in the origin field MUST 
     256     * increment by one from the previous SDP. 
     257     */ 
     258    pj_strdup(pool, &new_offer->origin.user, &old_offer->origin.user); 
     259    new_offer->origin.id = old_offer->origin.id; 
     260    new_offer->origin.version = old_offer->origin.version + 1; 
     261    pj_strdup(pool, &new_offer->origin.net_type, &old_offer->origin.net_type); 
     262    pj_strdup(pool, &new_offer->origin.addr_type,&old_offer->origin.addr_type); 
     263    pj_strdup(pool, &new_offer->origin.addr, &old_offer->origin.addr); 
     264 
     265    /* Generating the new offer, in the case media lines doesn't match the 
     266     * active SDP (e.g. current/active SDP's have m=audio and m=video lines,  
     267     * and the new offer only has m=audio line), the negotiator will fix  
     268     * the new offer by reordering and adding the missing media line with  
     269     * port number set to zero. 
     270     */ 
     271    for (oi = 0; oi < old_offer->media_count; ++oi) { 
     272        pjmedia_sdp_media *om; 
     273        pjmedia_sdp_media *nm; 
     274        unsigned ni; /* new offer media index */ 
     275        pj_bool_t found = PJ_FALSE; 
     276 
     277        om = old_offer->media[oi]; 
     278        for (ni = oi; ni < new_offer->media_count; ++ni) { 
     279            nm = new_offer->media[ni]; 
     280            if (pj_strcmp(&nm->desc.media, &om->desc.media) == 0) { 
     281                if (ni != oi) { 
     282                    /* The same media found but the position unmatched to the  
     283                     * old offer, so let's put this media in the right place,  
     284                     * and keep the order of the rest. 
     285                     */ 
     286                    pj_array_insert(new_offer->media,            /* array    */ 
     287                                    sizeof(new_offer->media[0]), /* elmt size*/ 
     288                                    ni,                          /* count    */ 
     289                                    oi,                          /* pos      */ 
     290                                    &nm);                        /* new elmt */ 
     291                } 
     292                found = PJ_TRUE; 
     293                break; 
     294            } 
     295        } 
     296        if (!found) { 
     297            pjmedia_sdp_media *m; 
     298 
     299            m = pjmedia_sdp_media_clone(pool, om); 
     300            m->desc.port = 0; 
     301 
     302            pj_array_insert(new_offer->media, sizeof(new_offer->media[0]), 
     303                            new_offer->media_count++, oi, &m); 
     304        } 
     305    } 
     306 
     307    /* New_offer fixed */ 
     308    neg->initial_sdp = new_offer; 
     309    neg->neg_local_sdp = pjmedia_sdp_session_clone(pool, new_offer); 
    238310 
    239311    return PJ_SUCCESS; 
     
    649721                                  pjmedia_sdp_session **p_active) 
    650722{ 
    651     unsigned mi; 
     723    unsigned omi = 0; /* Offer media index */ 
     724    unsigned ami = 0; /* Answer media index */ 
    652725    pj_bool_t has_active = PJ_FALSE; 
    653726    pj_status_t status; 
     
    657730 
    658731    /* Check that media count match between offer and answer */ 
    659     if (offer->media_count != answer->media_count) 
    660         return PJMEDIA_SDPNEG_EMISMEDIA; 
     732    // Ticket #527, different media count is allowed for more interoperability, 
     733    // however, the media order must be same between offer and answer. 
     734    // if (offer->media_count != answer->media_count) 
     735    //     return PJMEDIA_SDPNEG_EMISMEDIA; 
    661736 
    662737    /* Now update each media line in the offer with the answer. */ 
    663     for (mi=0; mi<offer->media_count; ++mi) { 
    664         status = process_m_answer(pool, offer->media[mi], answer->media[mi], 
     738    for (; omi<offer->media_count; ++omi) { 
     739        if (ami == answer->media_count) { 
     740            /* No answer media to be negotiated */ 
     741            offer->media[omi]->desc.port = 0; 
     742            continue; 
     743        } 
     744 
     745        status = process_m_answer(pool, offer->media[omi], answer->media[ami], 
    665746                                  allow_asym); 
     747 
     748        /* If media type is mismatched, just disable the media. */ 
     749        if (status == PJMEDIA_SDPNEG_EINVANSMEDIA) { 
     750            offer->media[omi]->desc.port = 0; 
     751            continue; 
     752        } 
     753 
    666754        if (status != PJ_SUCCESS) 
    667755            return status; 
    668756 
    669         if (offer->media[mi]->desc.port != 0) 
     757        if (offer->media[omi]->desc.port != 0) 
    670758            has_active = PJ_TRUE; 
     759 
     760        ++ami; 
    671761    } 
    672762 
     
    9461036             * Reject the offer by setting the port to zero in the answer. 
    9471037             */ 
    948             pjmedia_sdp_attr *a; 
     1038            //pjmedia_sdp_attr *a; 
    9491039 
    9501040            /* For simplicity in the construction of the answer, we'll 
     
    9561046            am->desc.port = 0; 
    9571047 
     1048            // Just set port zero to disable stream without set it to inactive. 
    9581049            /* Remove direction attribute, and replace with inactive */ 
    9591050            remove_all_media_directions(am); 
    960  
    961             a = pjmedia_sdp_attr_create(pool, "inactive", NULL); 
    962             pjmedia_sdp_media_add_attr(am, a); 
     1051            //a = pjmedia_sdp_attr_create(pool, "inactive", NULL); 
     1052            //pjmedia_sdp_media_add_attr(am, a); 
     1053 
     1054            /* Then update direction */ 
     1055            update_media_direction(pool, om, am); 
    9631056 
    9641057        } else { 
Note: See TracChangeset for help on using the changeset viewer.