Ignore:
Timestamp:
Jun 29, 2006 2:45:17 PM (18 years ago)
Author:
bennylp
Message:

Improvements in PJMEDIA to support RFC 3605 (RTCP attribute in SDP) and other changes to improve RTCP communication behind NAT. Also fixed bug related to RTCP reporting changes in revision 565

File:
1 edited

Legend:

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

    r366 r568  
    6060static void parse_media(pj_scanner *scanner, pjmedia_sdp_media *med, 
    6161                        parse_context *ctx); 
    62  
     62static void on_scanner_error(pj_scanner *scanner); 
    6363 
    6464/* 
     
    242242                                                 pjmedia_sdp_rtpmap *rtpmap) 
    243243{ 
    244     const char *p = attr->value.ptr; 
    245     const char *end = attr->value.ptr + attr->value.slen; 
     244    pj_scanner scanner; 
    246245    pj_str_t token; 
     246    pj_status_t status = -1; 
     247    PJ_USE_EXCEPTION; 
    247248 
    248249    PJ_ASSERT_RETURN(pj_strcmp2(&attr->name, "rtpmap")==0, PJ_EINVALIDOP); 
     250 
     251    pj_scan_init(&scanner, (char*)attr->value.ptr, attr->value.slen, 
     252                 PJ_SCAN_AUTOSKIP_WS, &on_scanner_error); 
    249253 
    250254    /* rtpmap sample: 
     
    252256     */ 
    253257 
    254     /* Eat the first ':' */ 
    255     if (*p != ':') return PJMEDIA_SDP_EINRTPMAP; 
    256  
    257     /* Get ':' */ 
    258     ++p; 
    259  
    260     /* Get payload type. */ 
    261     token.ptr = (char*)p; 
    262     while (pj_isdigit(*p) && p!=end) 
    263         ++p; 
    264     token.slen = p - token.ptr; 
    265     if (token.slen == 0) 
    266         return PJMEDIA_SDP_EINRTPMAP; 
    267  
    268     rtpmap->pt = token; 
    269  
    270     /* Expecting space after payload type. */ 
    271     if (*p != ' ') return PJMEDIA_SDP_EINRTPMAP; 
    272  
    273     /* Get space. */ 
    274     ++p; 
    275  
    276     /* Get encoding name. */ 
    277     token.ptr = (char*)p; 
    278     while (*p != '/' && p != end) 
    279         ++p; 
    280     token.slen = p - token.ptr; 
    281     if (token.slen == 0) 
    282         return PJMEDIA_SDP_EINRTPMAP; 
    283     rtpmap->enc_name = token; 
    284  
    285     /* Expecting '/' after encoding name. */ 
    286     if (*p != '/') return PJMEDIA_SDP_EINRTPMAP; 
    287  
    288     /* Get '/' */ 
    289     ++p; 
    290  
    291     /* Get the clock rate. */ 
    292     token.ptr = (char*)p; 
    293     while (p != end && pj_isdigit(*p)) 
    294         ++p; 
    295     token.slen = p - token.ptr; 
    296     if (token.slen == 0) 
    297         return PJMEDIA_SDP_EINRTPMAP; 
    298  
    299     rtpmap->clock_rate = pj_strtoul(&token); 
    300  
    301     /* Expecting either '/' or EOF */ 
    302     if (p != end && *p != '/') 
    303         return PJMEDIA_SDP_EINRTPMAP; 
    304  
    305     if (p != end) { 
    306         ++p; 
    307         token.ptr = (char*)p; 
    308         token.slen = end-p; 
    309         rtpmap->param = token; 
    310     } else { 
    311         rtpmap->param.ptr = NULL; 
    312         rtpmap->param.slen = 0; 
    313     } 
    314  
    315     return PJ_SUCCESS; 
    316  
     258    /* Init */ 
     259    rtpmap->pt.slen = rtpmap->param.slen = rtpmap->enc_name.slen = 0; 
     260 
     261    /* Parse */ 
     262    PJ_TRY { 
     263        /* Eat the first ':' */ 
     264        if (pj_scan_get_char(&scanner) != ':') { 
     265            status = PJMEDIA_SDP_EINRTPMAP; 
     266            goto on_return; 
     267        } 
     268 
     269 
     270        /* Get payload type. */ 
     271        pj_scan_get(&scanner, &cs_token, &rtpmap->pt); 
     272 
     273 
     274        /* Get encoding name. */ 
     275        pj_scan_get(&scanner, &cs_token, &rtpmap->enc_name); 
     276 
     277        /* Expecting '/' after encoding name. */ 
     278        if (pj_scan_get_char(&scanner) != '/') { 
     279            status = PJMEDIA_SDP_EINRTPMAP; 
     280            goto on_return; 
     281        } 
     282 
     283 
     284        /* Get the clock rate. */ 
     285        pj_scan_get(&scanner, &cs_token, &token); 
     286        rtpmap->clock_rate = pj_strtoul(&token); 
     287 
     288        /* Expecting either '/' or EOF */ 
     289        if (*scanner.curptr == '/') { 
     290            pj_scan_get_char(&scanner); 
     291            rtpmap->param.ptr = scanner.curptr; 
     292            rtpmap->param.slen = scanner.end - scanner.curptr; 
     293        } else { 
     294            rtpmap->param.slen = 0; 
     295        } 
     296 
     297        status = PJ_SUCCESS; 
     298    } 
     299    PJ_CATCH(SYNTAX_ERROR) { 
     300        status = PJMEDIA_SDP_EINRTPMAP; 
     301    } 
     302    PJ_END; 
     303 
     304 
     305on_return: 
     306    pj_scan_fini(&scanner); 
     307    return status; 
    317308} 
    318309 
     
    359350} 
    360351 
     352 
     353PJ_DEF(pj_status_t) pjmedia_sdp_attr_get_rtcp(const pjmedia_sdp_attr *attr, 
     354                                              pjmedia_sdp_rtcp_attr *rtcp) 
     355{ 
     356    pj_scanner scanner; 
     357    pj_str_t token; 
     358    pj_status_t status = -1; 
     359    PJ_USE_EXCEPTION; 
     360 
     361    PJ_ASSERT_RETURN(pj_strcmp2(&attr->name, "rtcp")==0, PJ_EINVALIDOP); 
     362 
     363    /* fmtp BNF: 
     364     *  a=rtcp:<port> [nettype addrtype address] 
     365     */ 
     366 
     367    pj_scan_init(&scanner, (char*)attr->value.ptr, attr->value.slen, 
     368                 PJ_SCAN_AUTOSKIP_WS, &on_scanner_error); 
     369 
     370    /* Init */ 
     371    rtcp->net_type.slen = rtcp->addr_type.slen = rtcp->addr.slen = 0; 
     372 
     373    /* Parse */ 
     374    PJ_TRY { 
     375 
     376        /* Get the first ":" */ 
     377        if (pj_scan_get_char(&scanner) != ':') 
     378        { 
     379            status = PJMEDIA_SDP_EINRTCP; 
     380            goto on_return; 
     381        } 
     382 
     383        /* Get the port */ 
     384        pj_scan_get(&scanner, &cs_token, &token); 
     385        rtcp->port = pj_strtoul(&token); 
     386 
     387        /* Have address? */ 
     388        if (!pj_scan_is_eof(&scanner)) { 
     389 
     390            /* Get network type */ 
     391            pj_scan_get(&scanner, &cs_token, &rtcp->net_type); 
     392 
     393            /* Get address type */ 
     394            pj_scan_get(&scanner, &cs_token, &rtcp->addr_type); 
     395 
     396            /* Get the address */ 
     397            pj_scan_get(&scanner, &cs_token, &rtcp->addr); 
     398 
     399        } 
     400 
     401        status = PJ_SUCCESS; 
     402 
     403    } 
     404    PJ_CATCH(SYNTAX_ERROR) { 
     405        status = PJMEDIA_SDP_EINRTCP; 
     406    } 
     407    PJ_END; 
     408 
     409on_return: 
     410    pj_scan_fini(&scanner); 
     411    return status; 
     412} 
     413 
     414 
     415 
    361416PJ_DEF(pj_status_t) pjmedia_sdp_attr_to_rtpmap(pj_pool_t *pool, 
    362417                                               const pjmedia_sdp_attr *attr, 
     
    377432{ 
    378433    pjmedia_sdp_attr *attr; 
    379     char tempbuf[64], *p, *endbuf; 
    380     int i; 
     434    char tempbuf[64]; 
     435    int len; 
    381436 
    382437    /* Check arguments. */ 
     
    387442                     PJMEDIA_SDP_EINRTPMAP); 
    388443 
    389     /* Check size. */ 
    390     i = rtpmap->enc_name.slen + rtpmap->param.slen + 32; 
    391     if (i >= sizeof(tempbuf)-1) { 
    392         pj_assert(!"rtpmap attribute is too long"); 
    393         return PJMEDIA_SDP_ERTPMAPTOOLONG; 
    394     } 
    395444 
    396445    attr = pj_pool_alloc(pool, sizeof(pjmedia_sdp_attr)); 
     
    400449    attr->name.slen = 6; 
    401450 
    402     p = tempbuf; 
    403     endbuf = tempbuf+sizeof(tempbuf); 
    404  
    405     /* Add colon */ 
    406     *p++ = ':'; 
    407  
    408     /* Add payload type. */ 
    409     pj_memcpy(p, rtpmap->pt.ptr, rtpmap->pt.slen); 
    410     p += rtpmap->pt.slen; 
    411     *p++ = ' '; 
    412  
    413     /* Add encoding name. */ 
    414     for (i=0; i<rtpmap->enc_name.slen; ++i) 
    415         p[i] = rtpmap->enc_name.ptr[i]; 
    416     p += rtpmap->enc_name.slen; 
    417     *p++ = '/'; 
    418  
    419     /* Add clock rate. */ 
    420     p += pj_utoa(rtpmap->clock_rate, p); 
    421  
    422     /* Add parameter if necessary. */ 
    423     if (rtpmap->param.slen > 0) { 
    424         *p++ = '/'; 
    425         for (i=0; i<rtpmap->param.slen; ++i) 
    426             p[i] = rtpmap->param.ptr[i]; 
    427         p += rtpmap->param.slen; 
    428     } 
    429  
    430     *p = '\0'; 
    431  
    432     attr->value.slen = p-tempbuf; 
     451    /* Format: ":pt enc_name/clock_rate[/param]" */ 
     452    len = pj_ansi_snprintf(tempbuf, sizeof(tempbuf),  
     453                           ":%.*s %.*s/%u%s%.*s", 
     454                           (int)rtpmap->pt.slen, 
     455                           rtpmap->pt.ptr, 
     456                           (int)rtpmap->enc_name.slen, 
     457                           rtpmap->enc_name.ptr, 
     458                           rtpmap->clock_rate, 
     459                           (rtpmap->param.slen ? "/" : ""), 
     460                           rtpmap->param.slen, 
     461                           rtpmap->param.ptr); 
     462 
     463    if (len < 1 || len > sizeof(tempbuf)) 
     464        return PJMEDIA_SDP_ERTPMAPTOOLONG; 
     465 
     466    attr->value.slen = len; 
    433467    attr->value.ptr = pj_pool_alloc(pool, attr->value.slen); 
    434468    pj_memcpy(attr->value.ptr, tempbuf, attr->value.slen); 
     
    441475static int print_connection_info( pjmedia_sdp_conn *c, char *buf, int len) 
    442476{ 
    443     char *p = buf; 
    444  
    445     if (len < 8+c->net_type.slen+c->addr_type.slen+c->addr.slen) { 
     477    int printed; 
     478 
     479    printed = pj_ansi_snprintf(buf, len, "c=%.*s %.*s %.*s\r\n", 
     480                               (int)c->net_type.slen, 
     481                               c->net_type.ptr, 
     482                               (int)c->addr_type.slen, 
     483                               c->addr_type.ptr, 
     484                               (int)c->addr.slen, 
     485                               c->addr.ptr); 
     486    if (printed < 1 || printed > len) 
    446487        return -1; 
    447     } 
    448     *p++ = 'c'; 
    449     *p++ = '='; 
    450     pj_memcpy(p, c->net_type.ptr, c->net_type.slen); 
    451     p += c->net_type.slen; 
    452     *p++ = ' '; 
    453     pj_memcpy(p, c->addr_type.ptr, c->addr_type.slen); 
    454     p += c->addr_type.slen; 
    455     *p++ = ' '; 
    456     pj_memcpy(p, c->addr.ptr, c->addr.slen); 
    457     p += c->addr.slen; 
    458     *p++ = '\r'; 
    459     *p++ = '\n'; 
    460  
    461     return p-buf; 
    462 } 
     488 
     489    return printed; 
     490} 
     491 
    463492 
    464493PJ_DEF(pjmedia_sdp_conn*) pjmedia_sdp_conn_clone (pj_pool_t *pool,  
Note: See TracChangeset for help on using the changeset viewer.