00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "ortp/ortp.h"
00022 #include "utils.h"
00023
00024
00025
00026
00027 bool_t rtcp_next_packet(mblk_t *m){
00028 const rtcp_common_header_t *ch=rtcp_get_common_header(m);
00029 if (ch){
00030 int nextlen=sizeof(rtcp_common_header_t)+
00031 (rtcp_common_header_get_length(ch)*4);
00032 if (m->b_rptr+nextlen<m->b_wptr){
00033 m->b_rptr+=nextlen;
00034 return TRUE;
00035 }
00036 }
00037 return FALSE;
00038 }
00039
00040 void rtcp_rewind(mblk_t *m){
00041 m->b_rptr=m->b_datap->db_base;
00042 }
00043
00044
00045 const rtcp_common_header_t * rtcp_get_common_header(const mblk_t *m){
00046 int size=msgdsize(m);
00047 rtcp_common_header_t *ch;
00048 if (m->b_cont!=NULL){
00049 ortp_fatal("RTCP parser does not work on fragmented mblk_t. Use msgpullup() before to re-assemble the packet.");
00050 return NULL;
00051 }
00052 if (size<sizeof(rtcp_common_header_t)){
00053 ortp_warning("Bad RTCP packet, too short.");
00054 return NULL;
00055 }
00056 ch=(rtcp_common_header_t*)m->b_rptr;
00057 return ch;
00058 }
00059
00060 bool_t rtcp_is_SR(const mblk_t *m){
00061 const rtcp_common_header_t *ch=rtcp_get_common_header(m);
00062 if (ch!=NULL && rtcp_common_header_get_packet_type(ch)==RTCP_SR){
00063 if (msgdsize(m)<sizeof(rtcp_sr_t)){
00064 ortp_warning("Too short RTCP SR packet.");
00065 return FALSE;
00066 }
00067 return TRUE;
00068 }
00069 return FALSE;
00070 }
00071
00072
00073 uint32_t rtcp_SR_get_ssrc(const mblk_t *m){
00074 rtcp_sr_t *sr=(rtcp_sr_t*)m->b_rptr;
00075 return ntohl(sr->ssrc);
00076 }
00077
00078 const sender_info_t * rtcp_SR_get_sender_info(const mblk_t *m){
00079 rtcp_sr_t *sr=(rtcp_sr_t*)m->b_rptr;
00080 return &sr->si;
00081 }
00082
00083 const report_block_t * rtcp_SR_get_report_block(const mblk_t *m, int idx){
00084 rtcp_sr_t *sr=(rtcp_sr_t*)m->b_rptr;
00085 report_block_t *rb=&sr->rb[idx];
00086 int size=sizeof(rtcp_common_header_t)+(4*rtcp_common_header_get_length(&sr->ch));
00087 if ( ( (uint8_t*)rb)+sizeof(report_block_t) <= m->b_rptr + size ) {
00088 return rb;
00089 }else{
00090 if (idx<rtcp_common_header_get_rc(&sr->ch)){
00091 ortp_warning("RTCP packet should include a report_block_t at pos %i but has no space for it.",idx);
00092 }
00093 }
00094 return NULL;
00095 }
00096
00097
00098 bool_t rtcp_is_RR(const mblk_t *m){
00099 const rtcp_common_header_t *ch=rtcp_get_common_header(m);
00100 if (ch!=NULL && rtcp_common_header_get_packet_type(ch)==RTCP_RR){
00101 if (msgdsize(m)<sizeof(rtcp_rr_t)){
00102 ortp_warning("Too short RTCP RR packet.");
00103 return FALSE;
00104 }
00105 return TRUE;
00106 }
00107 return FALSE;
00108 }
00109
00110 uint32_t rtcp_RR_get_ssrc(const mblk_t *m){
00111 rtcp_rr_t *rr=(rtcp_rr_t*)m->b_rptr;
00112 return ntohl(rr->ssrc);
00113 }
00114
00115 const report_block_t * rtcp_RR_get_report_block(const mblk_t *m,int idx){
00116 rtcp_rr_t *rr=(rtcp_rr_t*)m->b_rptr;
00117 report_block_t *rb=&rr->rb[idx];
00118 int size=sizeof(rtcp_common_header_t)+(4*rtcp_common_header_get_length(&rr->ch));
00119 if ( ( (uint8_t*)rb)+sizeof(report_block_t) <= (m->b_rptr + size ) ){
00120 return rb;
00121 }else{
00122 if (idx<rtcp_common_header_get_rc(&rr->ch)){
00123 ortp_warning("RTCP packet should include a report_block_t at pos %i but has no space for it.",idx);
00124 }
00125 }
00126 return NULL;
00127 }
00128
00129
00130 bool_t rtcp_is_SDES(const mblk_t *m){
00131 const rtcp_common_header_t *ch=rtcp_get_common_header(m);
00132 if (ch && rtcp_common_header_get_packet_type(ch)==RTCP_SDES){
00133 if (msgdsize(m)<sizeof(rtcp_common_header_t)+
00134 (4*rtcp_common_header_get_length(ch))){
00135 ortp_warning("Too short RTCP SDES packet.");
00136 return FALSE;
00137 }
00138 return TRUE;
00139 }
00140 return FALSE;
00141 }
00142
00143 void rtcp_sdes_parse(const mblk_t *m, SdesItemFoundCallback cb, void *user_data){
00144 uint8_t *rptr=(uint8_t*)m->b_rptr+sizeof(rtcp_common_header_t);
00145 const rtcp_common_header_t *ch=(rtcp_common_header_t*)m->b_rptr;
00146 uint8_t *end=rptr+sizeof(rtcp_common_header_t)+
00147 (4*rtcp_common_header_get_length(ch));
00148 uint32_t ssrc=0;
00149 int nchunk=0;
00150 bool_t chunk_start=TRUE;
00151
00152 if (end>(uint8_t*)m->b_wptr) end=(uint8_t*)m->b_wptr;
00153
00154 while(rptr<end){
00155 if (chunk_start){
00156 if (rptr+4<=end){
00157 ssrc=ntohl(*(uint32_t*)rptr);
00158 rptr+=4;
00159 }else{
00160 ortp_warning("incorrect chunk start in RTCP SDES");
00161 break;
00162 }
00163 chunk_start=FALSE;
00164 }else{
00165 if (rptr+2<=end){
00166 uint8_t type=rptr[0];
00167 uint8_t len=rptr[1];
00168
00169 if (type==RTCP_SDES_END){
00170
00171 rptr=(uint8_t*)(((unsigned long)rptr+4) & ~0x3);
00172 nchunk++;
00173 if (nchunk<rtcp_common_header_get_rc(ch)){
00174 chunk_start=TRUE;
00175 continue;
00176 }else break;
00177 }
00178 rptr+=2;
00179 if (rptr+len<=end){
00180 cb(user_data,ssrc,type,(char*)rptr,len);
00181 rptr+=len;
00182 }else{
00183 ortp_warning("bad item length in RTCP SDES");
00184 break;
00185 }
00186 }else{
00187
00188 break;
00189 }
00190 }
00191 }
00192 }
00193
00194
00195 bool_t rtcp_is_BYE(const mblk_t *m){
00196 const rtcp_common_header_t *ch=rtcp_get_common_header(m);
00197 if (ch && rtcp_common_header_get_packet_type(ch)==RTCP_BYE){
00198 if (msgdsize(m)<sizeof(rtcp_common_header_t)+
00199 rtcp_common_header_get_length(ch)){
00200 ortp_warning("Too short RTCP BYE packet.");
00201 return FALSE;
00202 }
00203 return TRUE;
00204 }
00205 return FALSE;
00206 }
00207
00208 bool_t rtcp_BYE_get_ssrc(const mblk_t *m, int idx, uint32_t *ssrc){
00209 rtcp_bye_t *bye=(rtcp_bye_t*)m->b_rptr;
00210 int rc=rtcp_common_header_get_rc(&bye->ch);
00211 int len=rtcp_common_header_get_length(&bye->ch);
00212 if (idx<rc){
00213 if ((uint8_t*)&bye->ssrc[idx]<=(m->b_rptr
00214 +sizeof(rtcp_common_header_t)+len-4)) {
00215 *ssrc=ntohl(bye->ssrc[idx]);
00216 return TRUE;
00217 }else{
00218 ortp_warning("RTCP BYE should contain %i ssrc, but there is not enough room for it.");
00219 }
00220 }
00221 return FALSE;
00222 }
00223
00224 bool_t rtcp_BYE_get_reason(const mblk_t *m, const char **reason, int *reason_len){
00225 rtcp_bye_t *bye=(rtcp_bye_t*)m->b_rptr;
00226 int rc=rtcp_common_header_get_rc(&bye->ch);
00227 int len=rtcp_common_header_get_length(&bye->ch);
00228 uint8_t *rptr=(uint8_t*)m->b_rptr+sizeof(rtcp_common_header_t)+rc*4;
00229 uint8_t *end=(uint8_t*)(m->b_rptr+sizeof(rtcp_common_header_t)+len);
00230 if (rptr<end){
00231 uint8_t content_len=rptr[0];
00232 if (rptr+1+content_len<=end){
00233 *reason=(char*)rptr+1;
00234 *reason_len=content_len;
00235 return TRUE;
00236 }else{
00237 ortp_warning("RTCP BYE has not enough space for reason phrase.");
00238 return FALSE;
00239 }
00240 }
00241 return FALSE;
00242 }
00243
00244
00245 bool_t rtcp_is_APP(const mblk_t *m){
00246 const rtcp_common_header_t *ch=rtcp_get_common_header(m);
00247 if (ch!=NULL && rtcp_common_header_get_packet_type(ch)==RTCP_APP){
00248 if (msgdsize(m)<sizeof(rtcp_common_header_t)+
00249 rtcp_common_header_get_length(ch)){
00250 ortp_warning("Too short RTCP APP packet.");
00251 return FALSE;
00252 }
00253 if (sizeof(rtcp_common_header_t)+rtcp_common_header_get_length(ch)
00254 < sizeof(rtcp_app_t)){
00255 ortp_warning("Bad RTCP APP packet.");
00256 return FALSE;
00257 }
00258 return TRUE;
00259 }
00260 return FALSE;
00261 }
00262
00263 int rtcp_APP_get_subtype(const mblk_t *m){
00264 rtcp_app_t *app=(rtcp_app_t*)m->b_rptr;
00265 return rtcp_common_header_get_rc(&app->ch);
00266 }
00267
00268 uint32_t rtcp_APP_get_ssrc(const mblk_t *m){
00269 rtcp_app_t *app=(rtcp_app_t*)m->b_rptr;
00270 return ntohl(app->ssrc);
00271 }
00272
00273 void rtcp_APP_get_name(const mblk_t *m, char *name){
00274 rtcp_app_t *app=(rtcp_app_t*)m->b_rptr;
00275 memcpy(name,app->name,4);
00276 }
00277
00278 void rtcp_APP_get_data(const mblk_t *m, uint8_t **data, int *len){
00279 rtcp_app_t *app=(rtcp_app_t*)m->b_rptr;
00280 int datalen=sizeof(rtcp_common_header_t)+rtcp_common_header_get_length(&app->ch)-8;
00281 if (datalen>0){
00282 *data=(uint8_t*)m->b_rptr+sizeof(rtcp_app_t);
00283 *len=datalen;
00284 }else{
00285 *len=0;
00286 *data=NULL;
00287 }
00288 }
00289
00290
00291
00292
00293
00294 void report_block_parse(RtpSession *session, report_block_t *rb, struct timeval rcv_time_tv)
00295 {
00296 rb->ssrc = ntohl(rb->ssrc);
00297
00298 if ( rb->ssrc != session->snd.ssrc )
00299
00300 {
00301 ortp_debug("Received rtcp report block related to unknown ssrc (not from us)... discarded");
00302 return;
00303 }
00304
00305 else
00306
00307 {
00308 uint32_t rcv_time_msw;
00309 uint32_t rcv_time_lsw;
00310 uint32_t rcv_time;
00311 double rtt;
00312
00313 rcv_time_msw = rcv_time_tv.tv_sec;
00314 #if defined(_WIN32_WCE)
00315 rcv_time_lsw = (uint32_t) ((double)rcv_time_tv.tv_usec*(double)(((uint64_t)1)<<32)*1.0e-6);
00316 #else
00317 rcv_time_lsw = (uint32_t) ((double)rcv_time_tv.tv_usec*(double)(1LL<<32)*1.0e-6);
00318 #endif
00319 rcv_time = (rcv_time_msw<<16) | (rcv_time_lsw >> 16);
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330 if (rb->lsr != 0)
00331 {
00332 rtt = (double) (rcv_time - rb->delay_snc_last_sr - rb->lsr);
00333 rtt = rtt/65536;
00334
00335 }
00336
00337 }
00338
00339 }
00340
00341 void rtp_session_rtcp_parse(RtpSession *session, mblk_t *mp)
00342 {
00343 rtcp_common_header_t *rtcp;
00344 int msgsize;
00345 int rtcp_pk_size;
00346 RtpStream *rtpstream=&session->rtp;
00347 struct timeval rcv_time_tv;
00348
00349
00350 gettimeofday(&rcv_time_tv,NULL);
00351
00352 return_if_fail(mp!=NULL);
00353
00354 msgsize=(int) (mp->b_wptr-mp->b_rptr);
00355
00356 if (msgsize < RTCP_COMMON_HEADER_SIZE)
00357 {
00358 ortp_debug("Receiving too short rtcp packet... discarded");
00359 return;
00360 }
00361
00362 rtcp=(rtcp_common_header_t *)mp->b_rptr;
00363
00364
00365 while (msgsize >= RTCP_COMMON_HEADER_SIZE)
00366 {
00367
00368 if (rtcp->version!=2)
00369 {
00370 ortp_debug("Receiving rtcp packet with version number !=2...discarded");
00371 return;
00372 }
00373
00374
00375 rtcp->length = ntohs(rtcp->length);
00376
00377
00378 rtcp_pk_size = (rtcp->length + 1) * 4;
00379
00380 if (rtcp_pk_size > msgsize)
00381 {
00382 ortp_debug("Receiving rtcp packet shorter than the specified length.. discared");
00383 return;
00384 }
00385
00386 switch (rtcp->packet_type)
00387
00388 {
00389
00390 case RTCP_SR:
00391
00392 {
00393 rtcp_sr_t *sr = (rtcp_sr_t *) rtcp;
00394 report_block_t *rb;
00395 int i;
00396
00397 if ( ntohl(sr->ssrc) != session->rcv.ssrc )
00398 {
00399 ortp_debug("Receiving rtcp sr packet from unknown ssrc.. discarded");
00400 return;
00401 }
00402
00403 if (msgsize < RTCP_COMMON_HEADER_SIZE + RTCP_SSRC_FIELD_SIZE + RTCP_SENDER_INFO_SIZE + (RTCP_REPORT_BLOCK_SIZE*sr->ch.rc))
00404 {
00405 ortp_debug("Receiving too short rtcp sr packet... discarded");
00406 return;
00407 }
00408
00409
00410 sr->si.ntp_timestamp_msw = ntohl(sr->si.ntp_timestamp_msw);
00411 sr->si.ntp_timestamp_lsw = ntohl(sr->si.ntp_timestamp_lsw);
00412 sr->si.rtp_timestamp = ntohl(sr->si.rtp_timestamp);
00413 sr->si.senders_packet_count = ntohl(sr->si.senders_packet_count);
00414 sr->si.senders_octet_count = ntohl(sr->si.senders_octet_count);
00415
00416
00417 rtpstream->last_rcv_SR_ts = (sr->si.ntp_timestamp_msw << 16) | (sr->si.ntp_timestamp_lsw >> 16);
00418 rtpstream->last_rcv_SR_time.tv_usec = rcv_time_tv.tv_usec;
00419 rtpstream->last_rcv_SR_time.tv_sec = rcv_time_tv.tv_sec;
00420
00421
00422
00423 for (i=0; i<sr->ch.rc; i++)
00424 {
00425 rb = &(sr->rb[i]);
00426 report_block_parse(session, rb, rcv_time_tv);
00427 }
00428
00429 }
00430 break;
00431
00432
00433
00434 case RTCP_RR:
00435
00436 {
00437 rtcp_rr_t *rr = (rtcp_rr_t *) rtcp;
00438 report_block_t *rb;
00439 int i;
00440
00441 if (session->rcv.ssrc == 0)
00442 {
00443
00444 session->rcv.ssrc = ntohl(rr->ssrc);
00445 }
00446 else if ( ntohl(rr->ssrc) != session->rcv.ssrc )
00447 {
00448 ortp_debug("Receiving rtcp rr packet from unknown ssrc.. discarded");
00449 return;
00450 }
00451
00452 if (msgsize < RTCP_COMMON_HEADER_SIZE + RTCP_SSRC_FIELD_SIZE + (RTCP_REPORT_BLOCK_SIZE*rr->ch.rc))
00453 {
00454 ortp_debug("Receiving too short rtcp sr packet... discarded");
00455 return;
00456 }
00457
00458
00459 for (i=0; i<rr->ch.rc; i++)
00460 {
00461 rb = &(rr->rb[i]);
00462 report_block_parse(session, rb, rcv_time_tv);
00463 }
00464
00465 }
00466 break;
00467
00468
00469 case RTCP_SDES:
00470
00471 break;
00472
00473
00474 case RTCP_BYE:
00475 {
00476 rtcp_bye_t *bye = (rtcp_bye_t *) rtcp;
00477 unsigned sclen = bye->ch.rc * 4;
00478 int reason_space_len = rtcp_pk_size
00479 - sizeof (rtcp_common_header_t)
00480 - sclen;
00481 int i;
00482 char *reason = NULL;
00483 bool_t rcv_ssrc_match = FALSE;
00484
00485 if (reason_space_len < 0) {
00486 ortp_debug("Receiving too short RTCP BYE packet... discarded");
00487 return;
00488 }
00489 for (i = 0; i < bye->ch.rc; i++) {
00490 if (ntohl(bye->ssrc[i]) == session->rcv.ssrc) {
00491 rcv_ssrc_match = TRUE;
00492 break;
00493 }
00494 }
00495 if (rcv_ssrc_match) {
00496 if (session->on_rtcp_bye.count > 0) {
00497
00498 if (reason_space_len > 1) {
00499 uint8_t *reasonbuf = (uint8_t *) rtcp
00500 + sizeof (rtcp_common_header_t)
00501 + sclen;
00502 if (reasonbuf[0] <= reason_space_len-1)
00503 reason = ortp_strndup((char *)(reasonbuf+1), reasonbuf[0]);
00504 else
00505 ortp_debug("Incorrect RTCP BYE reason length");
00506 }
00507 rtp_signal_table_emit2(&session->on_rtcp_bye,
00508 (long)reason);
00509 if (reason)
00510 ortp_free(reason);
00511 } else {
00512 ortp_debug("Got RTCP BYE without RTCP BYE handler");
00513 }
00514 } else {
00515 ortp_debug("No SSRC in the BYE packet matched our rcv.ssrc.");
00516 }
00517 break;
00518 }
00519
00520 case RTCP_APP:
00521
00522 break;
00523
00524
00525 default:
00526
00527 ortp_debug("Receiving unknown rtcp packet type... discarded");
00528 return;
00529
00530 }
00531
00532
00533 msgsize -= rtcp_pk_size;
00534 rtcp = (rtcp_common_header_t *) (rtcp_pk_size + (char *) rtcp);
00535
00536 }
00537
00538
00539
00540 session->last_recv_time = rcv_time_tv;
00541 }