From fad7ca9f3f35cb1e116036f8cb11f51a95c7d788 Mon Sep 17 00:00:00 2001 From: Benny Prijono Date: Tue, 13 Mar 2007 13:07:37 +0000 Subject: Fixed ticket #171: SDP media direction negotiation bug (thanks Phil Torre) git-svn-id: http://svn.pjsip.org/repos/pjproject/branches/pjproject-0.5-stable@1057 74dad513-b988-da41-8d7b-12977e46ad98 --- pjmedia/src/pjmedia/sdp_neg.c | 96 +++++++++++++++++++++++++++++-------------- 1 file changed, 66 insertions(+), 30 deletions(-) diff --git a/pjmedia/src/pjmedia/sdp_neg.c b/pjmedia/src/pjmedia/sdp_neg.c index 27f4bcc0..aab409e3 100644 --- a/pjmedia/src/pjmedia/sdp_neg.c +++ b/pjmedia/src/pjmedia/sdp_neg.c @@ -368,53 +368,89 @@ static void update_media_direction(pj_pool_t *pool, const pjmedia_sdp_media *remote, pjmedia_sdp_media *local) { - if (pjmedia_sdp_media_find_attr2(remote, "inactive", NULL) != NULL) { - /* If remote has "a=inactive", then local is inactive too */ + pjmedia_dir old_dir = PJMEDIA_DIR_ENCODING_DECODING, + new_dir; - pjmedia_sdp_attr *a; + /* Get the media direction of local SDP */ + if (pjmedia_sdp_media_find_attr2(local, "sendonly", NULL)) + old_dir = PJMEDIA_DIR_ENCODING; + else if (pjmedia_sdp_media_find_attr2(local, "recvonly", NULL)) + old_dir = PJMEDIA_DIR_DECODING; + else if (pjmedia_sdp_media_find_attr2(local, "inactive", NULL)) + old_dir = PJMEDIA_DIR_NONE; - remove_all_media_directions(local); + new_dir = old_dir; + + /* Adjust local media direction based on remote media direction */ + if (pjmedia_sdp_media_find_attr2(remote, "inactive", NULL) != NULL) { + /* If remote has "a=inactive", then local is inactive too */ - a = pjmedia_sdp_attr_create(pool, "inactive", NULL); - pjmedia_sdp_media_add_attr(local, a); + new_dir = PJMEDIA_DIR_NONE; } else if(pjmedia_sdp_media_find_attr2(remote, "sendonly", NULL) != NULL) { /* If remote has "a=sendonly", then set local to "recvonly" if - * it is currently "sendrecv". + * it is currently "sendrecv". Otherwise if local is NOT "recvonly", + * then set local direction to "inactive". */ - - pjmedia_sdp_attr *a; - - remove_all_media_directions(local); - - a = pjmedia_sdp_attr_create(pool, "recvonly", NULL); - pjmedia_sdp_media_add_attr(local, a); + switch (old_dir) { + case PJMEDIA_DIR_ENCODING_DECODING: + new_dir = PJMEDIA_DIR_DECODING; + break; + case PJMEDIA_DIR_DECODING: + /* No change */ + break; + default: + new_dir = PJMEDIA_DIR_NONE; + break; + } } else if(pjmedia_sdp_media_find_attr2(remote, "recvonly", NULL) != NULL) { /* If remote has "a=recvonly", then set local to "sendonly" if - * it is currently "sendrecv". + * it is currently "sendrecv". Otherwise if local is NOT "sendonly", + * then set local direction to "inactive" */ - pjmedia_sdp_attr *a; - - remove_all_media_directions(local); - - a = pjmedia_sdp_attr_create(pool, "sendonly", NULL); - pjmedia_sdp_media_add_attr(local, a); + switch (old_dir) { + case PJMEDIA_DIR_ENCODING_DECODING: + new_dir = PJMEDIA_DIR_ENCODING; + break; + case PJMEDIA_DIR_ENCODING: + /* No change */ + break; + default: + new_dir = PJMEDIA_DIR_NONE; + break; + } - } else if(pjmedia_sdp_media_find_attr2(remote, "sendrecv", NULL) != NULL) { + } else { + /* Remote indicates "sendrecv" capability. No change to local + * direction + */ + } - pjmedia_sdp_attr *a; + if (new_dir != old_dir) { + pjmedia_sdp_attr *a = NULL; remove_all_media_directions(local); - a = pjmedia_sdp_attr_create(pool, "sendrecv", NULL); - pjmedia_sdp_media_add_attr(local, a); - - } else { - /* Otherwise remote is set to "sendrecv". - */ - remove_all_media_directions(local); + switch (new_dir) { + case PJMEDIA_DIR_NONE: + a = pjmedia_sdp_attr_create(pool, "inactive", NULL); + break; + case PJMEDIA_DIR_ENCODING: + a = pjmedia_sdp_attr_create(pool, "sendonly", NULL); + break; + case PJMEDIA_DIR_DECODING: + a = pjmedia_sdp_attr_create(pool, "recvonly", NULL); + break; + default: + /* sendrecv */ + break; + } + + if (a) { + pjmedia_sdp_media_add_attr(local, a); + } } } -- cgit v1.2.3