From 5d4b53b6e856f3d39347678ab48d8ebad52214cb Mon Sep 17 00:00:00 2001 From: Benny Prijono Date: Sun, 2 Jul 2006 12:29:54 +0000 Subject: [PATCH] Miscellaneous bug fix and improvements in PJMEDIA: (1) more stricker SDP parsing and validation, (2) fixed bug in RTCP attribute generation in SDP, (3) configurable telephone-event payload type git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@571 74dad513-b988-da41-8d7b-12977e46ad98 --- pjmedia/include/pjmedia-codec/types.h | 6 +-- pjmedia/include/pjmedia/config.h | 23 ++++++++++ pjmedia/src/pjmedia/endpoint.c | 20 ++++++--- pjmedia/src/pjmedia/sdp.c | 61 +++++++++++++++++++++++++-- pjmedia/src/pjmedia/session.c | 10 +++++ 5 files changed, 106 insertions(+), 14 deletions(-) diff --git a/pjmedia/include/pjmedia-codec/types.h b/pjmedia/include/pjmedia-codec/types.h index c115a8306..e28c9f38a 100644 --- a/pjmedia/include/pjmedia-codec/types.h +++ b/pjmedia/include/pjmedia-codec/types.h @@ -29,10 +29,10 @@ */ enum { - /* Telephone events must have pt=101, or otherwise some code needs - * to be updated (this would not affect outgoing pt). + /* PJMEDIA_RTP_PT_TELEPHONE_EVENTS is declared in + * */ - PJMEDIA_RTP_PT_TELEPHONE_EVENTS = 101, /**< telephone-events */ + PJMEDIA_RTP_PT_START = PJMEDIA_RTP_PT_TELEPHONE_EVENTS, PJMEDIA_RTP_PT_SPEEX_NB, /**< Speex narrowband/8KHz */ PJMEDIA_RTP_PT_SPEEX_WB, /**< Speex wideband/16KHz */ diff --git a/pjmedia/include/pjmedia/config.h b/pjmedia/include/pjmedia/config.h index f4bfeae41..f97fb79ff 100644 --- a/pjmedia/include/pjmedia/config.h +++ b/pjmedia/include/pjmedia/config.h @@ -163,6 +163,29 @@ #endif +/** + * This macro declares the payload type for telephone-event + * that is advertised by PJMEDIA for outgoing SDP. If this macro + * is set to zero, telephone events would not be advertised nor + * supported. + * + * If this value is changed to other number, please update the + * PJMEDIA_RTP_PT_TELEPHONE_EVENTS_STR too. + */ +#ifndef PJMEDIA_RTP_PT_TELEPHONE_EVENTS +# define PJMEDIA_RTP_PT_TELEPHONE_EVENTS 101 +#endif + + +/** + * Macro to get the string representation of the telephone-event + * payload type. + */ +#ifndef PJMEDIA_RTP_PT_TELEPHONE_EVENTS_STR +# define PJMEDIA_RTP_PT_TELEPHONE_EVENTS_STR "101" +#endif + + /** * @} diff --git a/pjmedia/src/pjmedia/endpoint.c b/pjmedia/src/pjmedia/endpoint.c index 24730f65e..c59a9eda5 100644 --- a/pjmedia/src/pjmedia/endpoint.c +++ b/pjmedia/src/pjmedia/endpoint.c @@ -332,7 +332,7 @@ PJ_DEF(pj_status_t) pjmedia_endpt_create_sdp( pjmedia_endpt *endpt, m->attr_count = 0; /* Add "rtcp" attribute */ -#if 1 +#if defined(PJMEDIA_HAS_RTCP_IN_SDP) && PJMEDIA_HAS_RTCP_IN_SDP!=0 { attr = pj_pool_alloc(pool, sizeof(pjmedia_sdp_attr)); attr->name = pj_str("rtcp"); @@ -340,8 +340,8 @@ PJ_DEF(pj_status_t) pjmedia_endpt_create_sdp( pjmedia_endpt *endpt, attr->value.slen = pj_ansi_snprintf(attr->value.ptr, 80, ":%u IN IP4 %s", - pj_ntohs(sock_info[0].rtp_addr_name.sin_port), - pj_inet_ntoa(sock_info[0].rtp_addr_name.sin_addr)); + pj_ntohs(sock_info[0].rtcp_addr_name.sin_port), + pj_inet_ntoa(sock_info[0].rtcp_addr_name.sin_addr)); pjmedia_sdp_attr_add(&m->attr_count, m->attr, attr); } #endif @@ -397,20 +397,26 @@ PJ_DEF(pj_status_t) pjmedia_endpt_create_sdp( pjmedia_endpt *endpt, attr->name = STR_SENDRECV; m->attr[m->attr_count++] = attr; -#if 1 +#if defined(PJMEDIA_RTP_PT_TELEPHONE_EVENTS) && \ + PJMEDIA_RTP_PT_TELEPHONE_EVENTS != 0 + /* * Add support telephony event */ - m->desc.fmt[m->desc.fmt_count++] = pj_str("101"); + m->desc.fmt[m->desc.fmt_count++] = + pj_str(PJMEDIA_RTP_PT_TELEPHONE_EVENTS_STR); + /* Add rtpmap. */ attr = pj_pool_zalloc(pool, sizeof(pjmedia_sdp_attr)); attr->name = pj_str("rtpmap"); - attr->value = pj_str(":101 telephone-event/8000"); + attr->value = pj_str(":" PJMEDIA_RTP_PT_TELEPHONE_EVENTS_STR + " telephone-event/8000"); m->attr[m->attr_count++] = attr; + /* Add fmtp */ attr = pj_pool_zalloc(pool, sizeof(pjmedia_sdp_attr)); attr->name = pj_str("fmtp"); - attr->value = pj_str(":101 0-15"); + attr->value = pj_str(":" PJMEDIA_RTP_PT_TELEPHONE_EVENTS_STR " 0-15"); m->attr[m->attr_count++] = attr; #endif diff --git a/pjmedia/src/pjmedia/sdp.c b/pjmedia/src/pjmedia/sdp.c index 835df4e4b..57e898741 100644 --- a/pjmedia/src/pjmedia/sdp.c +++ b/pjmedia/src/pjmedia/sdp.c @@ -34,6 +34,7 @@ enum { SYNTAX_ERROR = 1, }; #define TOKEN "-.!%*_=`'~" +//#define TOKEN "'`-./:?\"#$&*;=@[]^_`{|}+~!" #define NTP_OFFSET ((pj_uint32_t)2208988800) #define THIS_FILE "sdp.c" @@ -66,7 +67,7 @@ static void on_scanner_error(pj_scanner *scanner); */ static int is_initialized; static pj_cis_buf_t cis_buf; -static pj_cis_t cs_token; +static pj_cis_t cs_digit, cs_token; static void init_sdp_parser(void) { @@ -78,10 +79,14 @@ static void init_sdp_parser(void) } pj_cis_buf_init(&cis_buf); + pj_cis_init(&cis_buf, &cs_token); pj_cis_add_alpha(&cs_token); pj_cis_add_num(&cs_token); pj_cis_add_str(&cs_token, TOKEN); + + pj_cis_init(&cis_buf, &cs_digit); + pj_cis_add_num(&cs_digit); } PJ_DEF(pjmedia_sdp_attr*) pjmedia_sdp_attr_create( pj_pool_t *pool, @@ -257,6 +262,7 @@ PJ_DEF(pj_status_t) pjmedia_sdp_attr_get_rtpmap( const pjmedia_sdp_attr *attr, /* Init */ rtpmap->pt.slen = rtpmap->param.slen = rtpmap->enc_name.slen = 0; + rtpmap->clock_rate = 0; /* Parse */ PJ_TRY { @@ -282,7 +288,7 @@ PJ_DEF(pj_status_t) pjmedia_sdp_attr_get_rtpmap( const pjmedia_sdp_attr *attr, /* Get the clock rate. */ - pj_scan_get(&scanner, &cs_token, &token); + pj_scan_get(&scanner, &cs_digit, &token); rtpmap->clock_rate = pj_strtoul(&token); /* Expecting either '/' or EOF */ @@ -760,6 +766,18 @@ static void parse_version(pj_scanner *scanner, parse_context *ctx) { ctx->last_error = PJMEDIA_SDP_EINVER; + /* check equal sign */ + if (*(scanner->curptr+1) != '=') { + on_scanner_error(scanner); + return; + } + + /* check version is 0 */ + if (*(scanner->curptr+2) != '0') { + on_scanner_error(scanner); + return; + } + pj_scan_advance_n(scanner, 3, SKIP_WS); pj_scan_get_newline(scanner); } @@ -771,6 +789,12 @@ static void parse_origin(pj_scanner *scanner, pjmedia_sdp_session *ses, ctx->last_error = PJMEDIA_SDP_EINORIGIN; + /* check equal sign */ + if (*(scanner->curptr+1) != '=') { + on_scanner_error(scanner); + return; + } + /* o= */ pj_scan_advance_n(scanner, 2, SKIP_WS); @@ -810,6 +834,12 @@ static void parse_time(pj_scanner *scanner, pjmedia_sdp_session *ses, ctx->last_error = PJMEDIA_SDP_EINTIME; + /* check equal sign */ + if (*(scanner->curptr+1) != '=') { + on_scanner_error(scanner); + return; + } + /* t= */ pj_scan_advance_n(scanner, 2, SKIP_WS); @@ -832,6 +862,12 @@ static void parse_generic_line(pj_scanner *scanner, pj_str_t *str, { ctx->last_error = PJMEDIA_SDP_EINSDP; + /* check equal sign */ + if (*(scanner->curptr+1) != '=') { + on_scanner_error(scanner); + return; + } + /* x= */ pj_scan_advance_n(scanner, 2, SKIP_WS); @@ -872,6 +908,12 @@ static void parse_media(pj_scanner *scanner, pjmedia_sdp_media *med, ctx->last_error = PJMEDIA_SDP_EINMEDIA; + /* check the equal sign */ + if (*(scanner->curptr+1) != '=') { + on_scanner_error(scanner); + return; + } + /* m= */ pj_scan_advance_n(scanner, 2, SKIP_WS); @@ -926,6 +968,12 @@ static pjmedia_sdp_attr *parse_attr( pj_pool_t *pool, pj_scanner *scanner, attr = pj_pool_alloc(pool, sizeof(pjmedia_sdp_attr)); + /* check equal sign */ + if (*(scanner->curptr+1) != '=') { + on_scanner_error(scanner); + return NULL; + } + /* skip a= */ pj_scan_advance_n(scanner, 2, SKIP_WS); @@ -1012,7 +1060,12 @@ PJ_DEF(pj_status_t) pjmedia_sdp_parse( pj_pool_t *pool, parse_version(&scanner, &ctx); break; default: - parse_generic_line(&scanner, &dummy, &ctx); + if (cur_name >= 'a' && cur_name <= 'z') + parse_generic_line(&scanner, &dummy, &ctx); + else { + ctx.last_error = PJMEDIA_SDP_EINSDP; + on_scanner_error(&scanner); + } break; } } @@ -1103,7 +1156,7 @@ pjmedia_sdp_session_clone( pj_pool_t *pool, #define CHECK(exp,ret) do { \ - pj_assert(exp); \ + /*pj_assert(exp);*/ \ if (!(exp)) \ return ret; \ } while (0) diff --git a/pjmedia/src/pjmedia/session.c b/pjmedia/src/pjmedia/session.c index fa8650e05..2bf7a8dd8 100644 --- a/pjmedia/src/pjmedia/session.c +++ b/pjmedia/src/pjmedia/session.c @@ -121,6 +121,14 @@ PJ_DEF(pj_status_t) pjmedia_stream_info_from_sdp( return PJMEDIA_EINVALIMEDIATYPE; } + /* Transport type must be equal */ + if (pj_stricmp(&rem_m->desc.transport, + &local_m->desc.transport) != 0) + { + si->type = PJMEDIA_TYPE_UNKNOWN; + return PJMEDIA_SDPNEG_EINVANSTP; + } + /* Media direction: */ if (local_m->desc.port == 0 || @@ -199,6 +207,8 @@ PJ_DEF(pj_status_t) pjmedia_stream_info_from_sdp( /* Get the payload number for receive channel. */ pt = pj_strtoul(&local_m->desc.fmt[0]); + pj_assert(PJMEDIA_RTP_PT_TELEPHONE_EVENTS==0 || + pt != PJMEDIA_RTP_PT_TELEPHONE_EVENTS); /* Get codec info. * For static payload types, get the info from codec manager.