Changeset 5748


Ignore:
Timestamp:
Feb 27, 2018 3:37:53 AM (14 months ago)
Author:
ming
Message:

Fixed #2098: Add SDP attribute SSRC and CNAME

Location:
pjproject/trunk
Files:
17 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/include/pjmedia/errno.h

    r5597 r5748  
    177177 */ 
    178178#define PJMEDIA_SDP_EINBANDW        (PJMEDIA_ERRNO_START+37)    /* 220037 */ 
     179/** 
     180 * @hideinitializer 
     181 * Invalid SDP "ssrc" attribute. 
     182 */ 
     183#define PJMEDIA_SDP_EINSSRC         (PJMEDIA_ERRNO_START+38)    /* 220038 */ 
    179184 
    180185 
  • pjproject/trunk/pjmedia/include/pjmedia/rtp.h

    r5460 r5748  
    190190    pj_uint16_t             out_pt;     /**< Default outgoing payload type. */ 
    191191    pj_uint32_t             out_extseq; /**< Outgoing extended seq #.       */ 
     192    pj_bool_t               has_peer_ssrc;/**< Has peer SSRC?               */ 
    192193    pj_uint32_t             peer_ssrc;  /**< Peer SSRC.                     */ 
    193194    pj_uint32_t             received;   /**< Number of received packets.    */ 
     
    249250                                         bit #1: sender SSRC 
    250251                                         bit #2: sequence 
    251                                          bit #3: timestamp                  */ 
     252                                         bit #3: timestamp 
     253                                         bit #4: peer SSRC                  */ 
    252254    int              default_pt;    /**< Default payload type.              */ 
    253255    pj_uint32_t      sender_ssrc;   /**< Sender SSRC.                       */ 
     256    pj_uint32_t      peer_ssrc;     /**< Peer SSRC.                         */ 
    254257    pj_uint16_t      seq;           /**< Sequence.                          */ 
    255258    pj_uint32_t      ts;            /**< Timestamp.                         */ 
  • pjproject/trunk/pjmedia/include/pjmedia/sdp.h

    r5697 r5748  
    332332PJ_DECL(pjmedia_sdp_attr*) pjmedia_sdp_attr_create_rtcp(pj_pool_t *pool, 
    333333                                                        const pj_sockaddr *a); 
     334 
     335 
     336/** 
     337 * This structure describes SDP \a ssrc attribute. 
     338 */ 
     339typedef struct pjmedia_sdp_ssrc_attr 
     340{ 
     341    pj_uint32_t ssrc;       /**< RTP SSRC.      */ 
     342    pj_str_t    cname;      /**< RTCP CNAME.    */ 
     343} pjmedia_sdp_ssrc_attr; 
     344 
     345 
     346/** 
     347 * Parse a generic SDP attribute to get SDP ssrc attribute values. 
     348 * 
     349 * @param attr          Generic attribute to be converted to ssrc, which 
     350 *                      name must be "ssrc". 
     351 * @param ssrc          SDP ssrc attribute to be initialized. 
     352 * 
     353 * @return              PJ_SUCCESS on success. 
     354 */ 
     355PJ_DECL(pj_status_t) pjmedia_sdp_attr_get_ssrc(const pjmedia_sdp_attr *attr, 
     356                                               pjmedia_sdp_ssrc_attr *rtcp); 
     357 
     358 
     359/** 
     360 * Create a=ssrc attribute. 
     361 * 
     362 * @param pool          Pool to create the attribute. 
     363 * @param ssrc          SSRC identifier. 
     364 * @param cname         CNAME. 
     365 * 
     366 * @return              SDP SSRC attribute. 
     367 */ 
     368PJ_DECL(pjmedia_sdp_attr*) pjmedia_sdp_attr_create_ssrc(pj_pool_t *pool, 
     369                                                        pj_uint32_t ssrc, 
     370                                                        const pj_str_t *cname); 
    334371 
    335372 
  • pjproject/trunk/pjmedia/include/pjmedia/stream.h

    r5479 r5748  
    117117    int                 rx_event_pt;/**< Incoming pt for telephone-events.  */ 
    118118    pj_uint32_t         ssrc;       /**< RTP SSRC.                          */ 
     119    pj_str_t            cname;      /**< RTCP CNAME.                        */ 
     120    pj_bool_t           has_rem_ssrc;/**<Has remote RTP SSRC?               */ 
     121    pj_uint32_t         rem_ssrc;   /**< Remote RTP SSRC.                   */ 
     122    pj_str_t            rem_cname;  /**< Remote RTCP CNAME.                 */ 
    119123    pj_uint32_t         rtp_ts;     /**< Initial RTP timestamp.             */ 
    120124    pj_uint16_t         rtp_seq;    /**< Initial RTP sequence number.       */ 
  • pjproject/trunk/pjmedia/include/pjmedia/vid_stream.h

    r5479 r5748  
    159159    unsigned            rx_pt;      /**< Incoming codec paylaod type.       */ 
    160160    pj_uint32_t         ssrc;       /**< RTP SSRC.                          */ 
     161    pj_str_t            cname;      /**< RTCP CNAME.                        */ 
     162    pj_bool_t           has_rem_ssrc;/**<Has remote RTP SSRC?               */ 
     163    pj_uint32_t         rem_ssrc;   /**< Remote RTP SSRC.                   */ 
     164    pj_str_t            rem_cname;  /**< Remote RTCP CNAME.                 */ 
    161165    pj_uint32_t         rtp_ts;     /**< Initial RTP timestamp.             */ 
    162166    pj_uint16_t         rtp_seq;    /**< Initial RTP sequence number.       */ 
  • pjproject/trunk/pjmedia/src/pjmedia/errno.c

    r5597 r5748  
    6565    PJ_BUILD_ERR( PJMEDIA_SDP_EINPT,        "Invalid SDP payload type in media line" ), 
    6666    PJ_BUILD_ERR( PJMEDIA_SDP_EINFMTP,      "Invalid SDP fmtp attribute" ), 
    67     PJ_BUILD_ERR( PJMEDIA_SDP_EINRTCP,      "Invalid SDP rtcp attribyte" ), 
     67    PJ_BUILD_ERR( PJMEDIA_SDP_EINRTCP,      "Invalid SDP rtcp attribute" ), 
    6868    PJ_BUILD_ERR( PJMEDIA_SDP_EINPROTO,     "Invalid SDP media transport protocol" ), 
    6969    PJ_BUILD_ERR( PJMEDIA_SDP_EINBANDW,     "Invalid SDP bandwidth info line" ), 
     70    PJ_BUILD_ERR( PJMEDIA_SDP_EINSSRC,      "Invalid SDP ssrc attribute" ), 
    7071 
    7172    /* SDP negotiator errors. */ 
  • pjproject/trunk/pjmedia/src/pjmedia/rtp.c

    r5460 r5748  
    109109    if (settings.flags & 8) 
    110110        ses->out_hdr.ts = pj_htonl(settings.ts); 
     111    if (settings.flags & 16) { 
     112        ses->has_peer_ssrc = PJ_TRUE; 
     113        ses->peer_ssrc = settings.peer_ssrc; 
     114    } 
    111115 
    112116    return PJ_SUCCESS; 
     
    238242 
    239243    /* Check SSRC. */ 
    240     if (ses->peer_ssrc == 0) ses->peer_ssrc = pj_ntohl(hdr->ssrc); 
     244    if (!ses->has_peer_ssrc && ses->peer_ssrc == 0) 
     245        ses->peer_ssrc = pj_ntohl(hdr->ssrc); 
    241246 
    242247    if (pj_ntohl(hdr->ssrc) != ses->peer_ssrc) { 
  • pjproject/trunk/pjmedia/src/pjmedia/sdp.c

    r5741 r5748  
    471471        return NULL; 
    472472    } 
     473 
     474    return attr; 
     475} 
     476 
     477 
     478PJ_DEF(pj_status_t) pjmedia_sdp_attr_get_ssrc(const pjmedia_sdp_attr *attr, 
     479                                              pjmedia_sdp_ssrc_attr *ssrc) 
     480{ 
     481    pj_scanner scanner; 
     482    pj_str_t token; 
     483    pj_status_t status = -1; 
     484    PJ_USE_EXCEPTION; 
     485 
     486    PJ_ASSERT_RETURN(pj_strcmp2(&attr->name, "ssrc")==0, PJ_EINVALIDOP); 
     487 
     488    if (attr->value.slen == 0) 
     489        return PJMEDIA_SDP_EINATTR; 
     490 
     491    init_sdp_parser(); 
     492 
     493    /* ssrc BNF: 
     494     *  a=ssrc:<ssrc-id> <attribute> 
     495     *  a=ssrc:<ssrc-id> <attribute>:<value> 
     496     */ 
     497 
     498    /* The buffer passed to the scanner is not guaranteed to be NULL 
     499     * terminated, but should be safe. See ticket #2063. 
     500     */ 
     501    pj_scan_init(&scanner, (char*)attr->value.ptr, attr->value.slen, 
     502                 PJ_SCAN_AUTOSKIP_WS, &on_scanner_error); 
     503 
     504    /* Init */ 
     505    pj_bzero(ssrc, sizeof(*ssrc)); 
     506 
     507    /* Parse */ 
     508    PJ_TRY { 
     509        pj_str_t attr; 
     510 
     511        /* Get the ssrc */ 
     512        pj_scan_get(&scanner, &cs_digit, &token); 
     513        ssrc->ssrc = pj_strtoul(&token); 
     514 
     515        pj_scan_get_char(&scanner); 
     516        pj_scan_get(&scanner, &cs_token, &attr); 
     517         
     518        /* Get cname attribute, if any */ 
     519        if (!pj_scan_is_eof(&scanner) && 
     520            pj_scan_get_char(&scanner) == ':' && 
     521            pj_strcmp2(&attr, "cname")) 
     522        { 
     523            pj_scan_get(&scanner, &cs_token, &ssrc->cname); 
     524        } 
     525 
     526        status = PJ_SUCCESS; 
     527 
     528    } 
     529    PJ_CATCH_ANY { 
     530        status = PJMEDIA_SDP_EINSSRC; 
     531    } 
     532    PJ_END; 
     533 
     534    pj_scan_fini(&scanner); 
     535    return status; 
     536} 
     537 
     538 
     539PJ_DEF(pjmedia_sdp_attr*) pjmedia_sdp_attr_create_ssrc( pj_pool_t *pool, 
     540                                                        pj_uint32_t ssrc, 
     541                                                        const pj_str_t *cname) 
     542{ 
     543    pjmedia_sdp_attr *attr; 
     544 
     545    if (cname->slen == 0) 
     546        return NULL; 
     547 
     548    attr = PJ_POOL_ALLOC_T(pool, pjmedia_sdp_attr); 
     549    attr->name = pj_str("ssrc"); 
     550    attr->value.ptr = (char*) pj_pool_alloc(pool, cname->slen+7 /* " cname:"*/ 
     551                                                  + 10 /* 32-bit integer */); 
     552    attr->value.slen = pj_ansi_snprintf(attr->value.ptr, cname->slen+17, 
     553                                        "%d cname:%.*s", ssrc, 
     554                                        (int)cname->slen, cname->ptr); 
    473555 
    474556    return attr; 
  • pjproject/trunk/pjmedia/src/pjmedia/stream.c

    r5734 r5748  
    20232023 
    20242024    /* Create RTP and RTCP sessions: */ 
    2025  
    2026     if (param->rtp_seq_ts_set == 0) { 
    2027         status = pjmedia_rtp_session_init(&channel->rtp, pt, param->ssrc); 
    2028     } else { 
     2025    { 
    20292026        pjmedia_rtp_session_setting settings; 
    20302027 
    2031         settings.flags = (pj_uint8_t)((param->rtp_seq_ts_set << 2) | 3); 
     2028        settings.flags = (pj_uint8_t)((param->rtp_seq_ts_set << 2) | 
     2029                                      (param->has_rem_ssrc << 4) | 3); 
    20322030        settings.default_pt = pt; 
    20332031        settings.sender_ssrc = param->ssrc; 
     2032        settings.peer_ssrc = param->rem_ssrc; 
    20342033        settings.seq = param->rtp_seq; 
    20352034        settings.ts = param->rtp_ts; 
     
    21252124#endif 
    21262125 
    2127     /* Build random RTCP CNAME. CNAME has user@host format */ 
    2128     stream->cname.ptr = p = (char*) pj_pool_alloc(pool, 20); 
    2129     pj_create_random_string(p, 5); 
    2130     p += 5; 
    2131     *p++ = '@'; *p++ = 'p'; *p++ = 'j'; 
    2132     pj_create_random_string(p, 6); 
    2133     p += 6; 
    2134     *p++ = '.'; *p++ = 'o'; *p++ = 'r'; *p++ = 'g'; 
    2135     stream->cname.slen = p - stream->cname.ptr; 
    2136  
     2126    stream->cname = info->cname; 
     2127    if (stream->cname.slen == 0) { 
     2128        /* Build random RTCP CNAME. CNAME has user@host format */ 
     2129        stream->cname.ptr = p = (char*) pj_pool_alloc(pool, 20); 
     2130        pj_create_random_string(p, 5); 
     2131        p += 5; 
     2132        *p++ = '@'; *p++ = 'p'; *p++ = 'j'; 
     2133        pj_create_random_string(p, 6); 
     2134        p += 6; 
     2135        *p++ = '.'; *p++ = 'o'; *p++ = 'r'; *p++ = 'g'; 
     2136        stream->cname.slen = p - stream->cname.ptr; 
     2137    } 
    21372138 
    21382139    /* Create mutex to protect jitter buffer: */ 
  • pjproject/trunk/pjmedia/src/pjmedia/stream_info.c

    r5597 r5748  
    367367    int rem_af, local_af; 
    368368    pj_sockaddr local_addr; 
     369    unsigned i; 
    369370    pj_status_t status; 
    370371 
     
    555556    } 
    556557 
     558    /* Check if "ssrc" attribute is present in the SDP. */ 
     559    for (i = 0; i < rem_m->attr_count; i++) { 
     560        if (pj_strcmp2(&rem_m->attr[i]->name, "ssrc") == 0) { 
     561            pjmedia_sdp_ssrc_attr ssrc; 
     562 
     563            status = pjmedia_sdp_attr_get_ssrc( 
     564                        (const pjmedia_sdp_attr *)rem_m->attr[i], &ssrc); 
     565            if (status == PJ_SUCCESS) { 
     566                si->has_rem_ssrc = PJ_TRUE; 
     567                si->rem_ssrc = ssrc.ssrc; 
     568                if (ssrc.cname.slen > 0) { 
     569                    pj_strdup(pool, &si->rem_cname, &ssrc.cname); 
     570                    break; 
     571                } 
     572            } 
     573        } 
     574    } 
    557575 
    558576    /* Get the payload number for receive channel. */ 
  • pjproject/trunk/pjmedia/src/pjmedia/vid_stream.c

    r5671 r5748  
    13611361 
    13621362    /* Create RTP and RTCP sessions: */ 
    1363     if (info->rtp_seq_ts_set == 0) { 
    1364         status = pjmedia_rtp_session_init(&channel->rtp, pt, info->ssrc); 
    1365     } else { 
     1363    { 
    13661364        pjmedia_rtp_session_setting settings; 
    13671365 
    1368         settings.flags = (pj_uint8_t)((info->rtp_seq_ts_set << 2) | 3); 
     1366        settings.flags = (pj_uint8_t)((info->rtp_seq_ts_set << 2) | 
     1367                                      (info->has_rem_ssrc << 4) | 3); 
    13691368        settings.default_pt = pt; 
    13701369        settings.sender_ssrc = info->ssrc; 
     1370        settings.peer_ssrc = info->rem_ssrc; 
    13711371        settings.seq = info->rtp_seq; 
    13721372        settings.ts = info->rtp_ts; 
     
    14971497    stream->num_keyframe = info->sk_cfg.count; 
    14981498 
    1499     /* Build random RTCP CNAME. CNAME has user@host format */ 
    1500     stream->cname.ptr = p = (char*) pj_pool_alloc(pool, 20); 
    1501     pj_create_random_string(p, 5); 
    1502     p += 5; 
    1503     *p++ = '@'; *p++ = 'p'; *p++ = 'j'; 
    1504     pj_create_random_string(p, 6); 
    1505     p += 6; 
    1506     *p++ = '.'; *p++ = 'o'; *p++ = 'r'; *p++ = 'g'; 
    1507     stream->cname.slen = p - stream->cname.ptr; 
    1508  
     1499    stream->cname = info->cname; 
     1500    if (stream->cname.slen == 0) { 
     1501        /* Build random RTCP CNAME. CNAME has user@host format */ 
     1502        stream->cname.ptr = p = (char*) pj_pool_alloc(pool, 20); 
     1503        pj_create_random_string(p, 5); 
     1504        p += 5; 
     1505        *p++ = '@'; *p++ = 'p'; *p++ = 'j'; 
     1506        pj_create_random_string(p, 6); 
     1507        p += 6; 
     1508        *p++ = '.'; *p++ = 'o'; *p++ = 'r'; *p++ = 'g'; 
     1509        stream->cname.slen = p - stream->cname.ptr; 
     1510    } 
    15091511 
    15101512    /* Create mutex to protect jitter buffer: */ 
  • pjproject/trunk/pjmedia/src/pjmedia/vid_stream_info.c

    r5746 r5748  
    196196    int rem_af, local_af; 
    197197    pj_sockaddr local_addr; 
     198    unsigned i; 
    198199    pj_status_t status; 
    199200 
     
    378379    } 
    379380 
     381    /* Check if "ssrc" attribute is present in the SDP. */ 
     382    for (i = 0; i < rem_m->attr_count; i++) { 
     383        if (pj_strcmp2(&rem_m->attr[i]->name, "ssrc") == 0) { 
     384            pjmedia_sdp_ssrc_attr ssrc; 
     385 
     386            status = pjmedia_sdp_attr_get_ssrc( 
     387                        (const pjmedia_sdp_attr *)rem_m->attr[i], &ssrc); 
     388            if (status == PJ_SUCCESS) { 
     389                si->has_rem_ssrc = PJ_TRUE; 
     390                si->rem_ssrc = ssrc.ssrc; 
     391                if (ssrc.cname.slen > 0) { 
     392                    pj_strdup(pool, &si->rem_cname, &ssrc.cname); 
     393                    break; 
     394                } 
     395            } 
     396        } 
     397    } 
     398 
    380399    /* Get codec info and param */ 
    381400    status = get_video_codec_info_param(si, pool, NULL, local_m, rem_m); 
  • pjproject/trunk/pjsip/include/pjsua-lib/pjsua_internal.h

    r5676 r5748  
    139139    pj_bool_t            local_hold;/**< Flag for call-hold by local.       */ 
    140140    void                *hold_msg;  /**< Outgoing hold tx_data.             */ 
     141    pj_str_t             cname;     /**< RTCP CNAME.                        */ 
     142    char                 cname_buf[16];/**< cname buffer.                   */ 
    141143 
    142144    unsigned             med_cnt;   /**< Number of media in SDP.            */ 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_aud.c

    r5717 r5748  
    604604        si->jb_max = pjsua_var.media_cfg.jb_max; 
    605605 
    606         /* Set SSRC */ 
     606        /* Set SSRC and CNAME */ 
    607607        si->ssrc = call_med->ssrc; 
     608        si->cname = call->cname; 
    608609 
    609610        /* Set RTP timestamp & sequence, normally these value are intialized 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c

    r5721 r5748  
    138138    call->index = id; 
    139139    call->last_text.ptr = call->last_text_buf_; 
     140    call->cname.ptr = call->cname_buf; 
     141    call->cname.slen = sizeof(call->cname_buf); 
    140142    for (i=0; i<PJ_ARRAY_SIZE(call->media); ++i) { 
    141143        pjsua_call_media *call_med = &call->media[i]; 
     
    793795    call->acc_id = acc_id; 
    794796    call->call_hold_type = acc->cfg.call_hold_type; 
     797 
     798    /* Generate per-session RTCP CNAME, according to RFC 7022. */ 
     799    pj_create_random_string(call->cname_buf, call->cname.slen); 
    795800 
    796801    /* Apply call setting */ 
     
    12231228 
    12241229    call = &pjsua_var.calls[call_id]; 
     1230 
     1231    /* Generate per-session RTCP CNAME, according to RFC 7022. */ 
     1232    pj_create_random_string(call->cname_buf, call->cname.slen); 
    12251233 
    12261234    /* Mark call start time. */ 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_media.c

    r5637 r5748  
    24152415        if (status != PJ_SUCCESS) 
    24162416            return status; 
     2417 
     2418        /* Add ssrc and cname attribute */ 
     2419        m->attr[m->attr_count++] = pjmedia_sdp_attr_create_ssrc(pool, 
     2420                                                                call_med->ssrc, 
     2421                                                                &call->cname); 
    24172422 
    24182423        sdp->media[sdp->media_count++] = m; 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_vid.c

    r5660 r5748  
    910910        si->jb_max = pjsua_var.media_cfg.jb_max; 
    911911 
    912         /* Set SSRC */ 
     912        /* Set SSRC and CNAME */ 
    913913        si->ssrc = call_med->ssrc; 
     914        si->cname = call->cname; 
    914915 
    915916        /* Set RTP timestamp & sequence, normally these value are intialized 
Note: See TracChangeset for help on using the changeset viewer.