static mblk_t *rtcp_create_simple_bye_packet(uint32_t ssrc, const char *reason) { int packet_size; int strsize = 0; int strpadding = 0; mblk_t *mp; rtcp_bye_t *rtcp; packet_size = RTCP_BYE_HEADER_SIZE; if (reason!=NULL) { strsize=(int)MIN(strlen(reason),RTCP_BYE_REASON_MAX_STRING_SIZE); if (strsize > 0) { strpadding = 3 - (strsize % 4); packet_size += 1 + strsize + strpadding; } } mp = allocb(packet_size, 0); rtcp = (rtcp_bye_t*)mp->b_rptr; rtcp_common_header_init(&rtcp->ch,NULL,RTCP_BYE,1,packet_size); rtcp->ssrc[0] = htonl(ssrc); mp->b_wptr += RTCP_BYE_HEADER_SIZE; /* append the reason if any*/ if (reason!=NULL) { const char pad[] = {0, 0, 0}; unsigned char strsize_octet = (unsigned char)strsize; appendb(mp, (const char*)&strsize_octet, 1, FALSE); appendb(mp, reason,strsize, FALSE); appendb(mp, pad,strpadding, FALSE); } return mp; }
mblk_t* rtp_session_create_rtcp_sdes_packet(RtpSession *session, bool_t full) { mblk_t *mp = allocb(sizeof(rtcp_common_header_t), 0); rtcp_common_header_t *rtcp; mblk_t *tmp; mblk_t *m = mp; mblk_t *sdes; queue_t *q; int rc = 0; sdes = (full == TRUE) ? session->full_sdes : session->minimal_sdes; rtcp = (rtcp_common_header_t *)mp->b_wptr; mp->b_wptr += sizeof(rtcp_common_header_t); /* Concatenate all sdes chunks. */ sdes_chunk_set_ssrc(sdes, session->snd.ssrc); m = concatb(m, dupmsg(sdes)); rc++; if (full == TRUE) { q = &session->contributing_sources; for (tmp = qbegin(q); !qend(q, tmp); tmp = qnext(q, mp)) { m = concatb(m, dupmsg(tmp)); rc++; } } rtcp_common_header_init(rtcp, session, RTCP_SDES, rc, msgdsize(mp)); return mp; }
static mblk_t * make_rtcp_fb_tmmbn(RtpSession *session, uint32_t ssrc) { int size = sizeof(rtcp_common_header_t) + sizeof(rtcp_fb_header_t) + sizeof(rtcp_fb_tmmbr_fci_t); mblk_t *h = allocb(size, 0); rtcp_common_header_t *ch; rtcp_fb_header_t *fbh; rtcp_fb_tmmbr_fci_t *fci; if (!session->rtcp.tmmbr_info.received) return NULL; /* Fill TMMBN */ ch = (rtcp_common_header_t *)h->b_wptr; h->b_wptr += sizeof(rtcp_common_header_t); fbh = (rtcp_fb_header_t *)h->b_wptr; h->b_wptr += sizeof(rtcp_fb_header_t); fci = (rtcp_fb_tmmbr_fci_t *)h->b_wptr; h->b_wptr += sizeof(rtcp_fb_tmmbr_fci_t); fbh->packet_sender_ssrc = htonl(rtp_session_get_send_ssrc(session)); fbh->media_source_ssrc = htonl(0); memcpy(fci, rtcp_RTPFB_tmmbr_get_fci(session->rtcp.tmmbr_info.received), sizeof(rtcp_fb_tmmbr_fci_t)); fci->ssrc = htonl(ssrc); /* Fill common header */ rtcp_common_header_init(ch, session, RTCP_RTPFB, RTCP_RTPFB_TMMBN, msgdsize(h)); return h; }
static mblk_t * make_rtcp_fb_fir(RtpSession *session) { int size = sizeof(rtcp_common_header_t) + sizeof(rtcp_fb_header_t) + sizeof(rtcp_fb_fir_fci_t); mblk_t *h = allocb(size, 0); rtcp_common_header_t *ch; rtcp_fb_header_t *fbh; rtcp_fb_fir_fci_t *fci; /* Fill FIR */ ch = (rtcp_common_header_t *)h->b_wptr; h->b_wptr += sizeof(rtcp_common_header_t); fbh = (rtcp_fb_header_t *)h->b_wptr; h->b_wptr += sizeof(rtcp_fb_header_t); fci = (rtcp_fb_fir_fci_t *)h->b_wptr; h->b_wptr += sizeof(rtcp_fb_fir_fci_t); fbh->packet_sender_ssrc = htonl(0); fbh->media_source_ssrc = htonl(rtp_session_get_recv_ssrc(session)); fci->ssrc = htonl(rtp_session_get_send_ssrc(session)); fci->seq_nr = session->rtcp.rtcp_fb_fir_seq_nr++; fci->pad1 = 0; fci->pad2 = 0; /* Fill common header */ rtcp_common_header_init(ch, session, RTCP_PSFB, RTCP_PSFB_FIR, msgdsize(h)); return h; }
static mblk_t * make_rtcp_fb_sli(RtpSession *session, uint16_t first, uint16_t number, uint8_t picture_id) { int size = sizeof(rtcp_common_header_t) + sizeof(rtcp_fb_header_t) + sizeof(rtcp_fb_sli_fci_t); mblk_t *h = allocb(size, 0); rtcp_common_header_t *ch; rtcp_fb_header_t *fbh; rtcp_fb_sli_fci_t *fci; /* Fill SLI */ ch = (rtcp_common_header_t *)h->b_wptr; h->b_wptr += sizeof(rtcp_common_header_t); fbh = (rtcp_fb_header_t *)h->b_wptr; h->b_wptr += sizeof(rtcp_fb_header_t); fci = (rtcp_fb_sli_fci_t *)h->b_wptr; h->b_wptr += sizeof(rtcp_fb_sli_fci_t); fbh->packet_sender_ssrc = htonl(rtp_session_get_send_ssrc(session)); fbh->media_source_ssrc = htonl(rtp_session_get_recv_ssrc(session)); rtcp_fb_sli_fci_set_first(fci, first); rtcp_fb_sli_fci_set_number(fci, number); rtcp_fb_sli_fci_set_picture_id(fci, picture_id); /* Fill common header */ rtcp_common_header_init(ch, session, RTCP_PSFB, RTCP_PSFB_SLI, msgdsize(h)); return h; }
int rtcp_rr_init(RtpSession *session, char *buf, int size){ rtcp_rr_t *rr=(rtcp_rr_t*)buf; if (size<sizeof(rtcp_rr_t)) return -1; rtcp_common_header_init(&rr->ch,session,RTCP_RR,1,sizeof(rtcp_sr_t)); rr->ssrc=htonl(session->send_ssrc); report_block_init(&rr->rb[0],session); return sizeof(rtcp_sr_t); }
static int rtcp_app_init(RtpSession *session, uint8_t *buf, uint8_t subtype, const char *name, int size){ rtcp_app_t *app=(rtcp_app_t*)buf; if (size<sizeof(rtcp_app_t)) return 0; rtcp_common_header_init(&app->ch,session,RTCP_APP,subtype,size); app->ssrc=htonl(session->snd.ssrc); memset(app->name,0,4); strncpy(app->name,name,4); return sizeof(rtcp_app_t); }
static int rtcp_rr_init(RtpSession *session, uint8_t *buf, int size){ rtcp_rr_t *rr=(rtcp_rr_t*)buf; if (size<sizeof(rtcp_rr_t)) return 0; rtcp_common_header_init(&rr->ch,session,RTCP_RR,1,sizeof(rtcp_rr_t)); rr->ssrc=htonl(session->snd.ssrc); report_block_init(&rr->rb[0],session); extended_statistics( session, &rr->rb[0] ); return sizeof(rtcp_rr_t); }
static int rtcp_sr_init(RtpSession *session, uint8_t *buf, int size){ rtcp_sr_t *sr=(rtcp_sr_t*)buf; int rr=(session->stats.packet_recv>0); int sr_size=sizeof(rtcp_sr_t)-sizeof(report_block_t)+(rr*sizeof(report_block_t)); if (size<sr_size) return 0; rtcp_common_header_init(&sr->ch,session,RTCP_SR,rr,sr_size); sr->ssrc=htonl(session->snd.ssrc); sender_info_init(&sr->si,session); /*only include a report block if packets were received*/ if (rr) { report_block_init( &sr->rb[0], session ); extended_statistics( session, &sr->rb[0] ); } return sr_size; }
static mblk_t * make_rtcp_fb_rpsi(RtpSession *session, uint8_t *bit_string, uint16_t bit_string_len) { uint16_t bit_string_len_in_bytes; int additional_bytes; int size; mblk_t *h; rtcp_common_header_t *ch; rtcp_fb_header_t *fbh; rtcp_fb_rpsi_fci_t *fci; int i; /* Calculate packet size and allocate memory. */ bit_string_len_in_bytes = (bit_string_len / 8) + (((bit_string_len % 8) == 0) ? 0 : 1); additional_bytes = bit_string_len_in_bytes - 2; if (additional_bytes < 0) additional_bytes = 0; size = sizeof(rtcp_common_header_t) + sizeof(rtcp_fb_header_t) + sizeof(rtcp_fb_rpsi_fci_t) + additional_bytes; h = allocb(size, 0); /* Fill RPSI */ ch = (rtcp_common_header_t *)h->b_wptr; h->b_wptr += sizeof(rtcp_common_header_t); fbh = (rtcp_fb_header_t *)h->b_wptr; h->b_wptr += sizeof(rtcp_fb_header_t); fci = (rtcp_fb_rpsi_fci_t *)h->b_wptr; h->b_wptr += sizeof(rtcp_fb_rpsi_fci_t); fbh->packet_sender_ssrc = htonl(rtp_session_get_send_ssrc(session)); fbh->media_source_ssrc = htonl(rtp_session_get_recv_ssrc(session)); if (bit_string_len <= 16) { fci->pb = 16 - bit_string_len; memset(&fci->bit_string, 0, 2); } else { fci->pb = (bit_string_len - 16) % 32; memset(&fci->bit_string, 0, bit_string_len_in_bytes); } fci->payload_type = rtp_session_get_recv_payload_type(session) & 0x7F; memcpy(&fci->bit_string, bit_string, bit_string_len / 8); for (i = 0; i < (bit_string_len % 8); i++) { fci->bit_string[bit_string_len_in_bytes - 1] |= (bit_string[bit_string_len_in_bytes - 1] & (1 << (7 - i))); } /* Fill common header */ rtcp_common_header_init(ch, session, RTCP_PSFB, RTCP_PSFB_RPSI, msgdsize(h)); return h; }
static mblk_t * make_rtcp_fb_pli(RtpSession *session) { int size = sizeof(rtcp_common_header_t) + sizeof(rtcp_fb_header_t); mblk_t *h= allocb(size, 0); rtcp_common_header_t *ch; rtcp_fb_header_t *fbh; /* Fill PLI */ ch = (rtcp_common_header_t *)h->b_wptr; h->b_wptr += sizeof(rtcp_common_header_t); fbh = (rtcp_fb_header_t *)h->b_wptr; h->b_wptr += sizeof(rtcp_fb_header_t); fbh->packet_sender_ssrc = htonl(rtp_session_get_send_ssrc(session)); fbh->media_source_ssrc = htonl(rtp_session_get_recv_ssrc(session)); /* Fill common header */ rtcp_common_header_init(ch, session, RTCP_PSFB, RTCP_PSFB_PLI, msgdsize(h)); return h; }
mblk_t *rtcp_create_simple_bye_packet(guint32 ssrc, const gchar *reason) { gint strsize=0; gint packet_size; mblk_t *mp; rtcp_bye_t *rtcp; packet_size = RTCP_BYE_HEADER_SIZE + 1 + strsize; if (reason!=NULL) strsize=MIN(strlen(reason),RTCP_BYE_REASON_MAX_STRING_SIZE); mp = allocb(packet_size, 0); rtcp = (rtcp_bye_t*)mp->b_rptr; rtcp_common_header_init(&rtcp->ch,NULL,RTCP_BYE,1,packet_size); rtcp->ssrc[0] = htonl(ssrc); mp->b_wptr += packet_size; /* append the reason if any*/ if (reason!=NULL) appendb(mp,reason,strsize,FALSE); return mp; }
static mblk_t * make_rtcp_fb_tmmbr(RtpSession *session, uint64_t mxtbr, uint16_t measured_overhead) { int size = sizeof(rtcp_common_header_t) + sizeof(rtcp_fb_header_t) + sizeof(rtcp_fb_tmmbr_fci_t); mblk_t *h = allocb(size, 0); rtcp_common_header_t *ch; rtcp_fb_header_t *fbh; rtcp_fb_tmmbr_fci_t *fci; uint8_t mxtbr_exp = 0; uint32_t mxtbr_mantissa = 0; /* Compute mxtbr exp and mantissa */ while (mxtbr >= (1 << 17)) { mxtbr >>= 1; mxtbr_exp++; } mxtbr_mantissa = mxtbr & 0x0001FFFF; /* Fill TMMBR */ ch = (rtcp_common_header_t *)h->b_wptr; h->b_wptr += sizeof(rtcp_common_header_t); fbh = (rtcp_fb_header_t *)h->b_wptr; h->b_wptr += sizeof(rtcp_fb_header_t); fci = (rtcp_fb_tmmbr_fci_t *)h->b_wptr; h->b_wptr += sizeof(rtcp_fb_tmmbr_fci_t); fbh->packet_sender_ssrc = htonl(rtp_session_get_send_ssrc(session)); fbh->media_source_ssrc = htonl(0); fci->ssrc = htonl(rtp_session_get_recv_ssrc(session)); rtcp_fb_tmmbr_fci_set_mxtbr_exp(fci, mxtbr_exp); rtcp_fb_tmmbr_fci_set_mxtbr_mantissa(fci, mxtbr_mantissa); rtcp_fb_tmmbr_fci_set_measured_overhead(fci, measured_overhead); /* Fill common header */ rtcp_common_header_init(ch, session, RTCP_RTPFB, RTCP_RTPFB_TMMBR, msgdsize(h)); /* Store packet to be able to retransmit. */ if (session->rtcp.tmmbr_info.sent) freemsg(session->rtcp.tmmbr_info.sent); session->rtcp.tmmbr_info.sent = copymsg(h); return h; }
mblk_t* rtp_session_create_rtcp_sdes_packet(RtpSession *session) { mblk_t *mp=allocb(sizeof(rtcp_common_header_t),0); rtcp_common_header_t *rtcp; mblk_t *tmp,*m=mp; queue_t *q; int rc=0; rtcp = (rtcp_common_header_t*)mp->b_wptr; mp->b_wptr+=sizeof(rtcp_common_header_t); /* concatenate all sdes chunks */ sdes_chunk_set_ssrc(session->sd,session->snd.ssrc); m=concatb(m,dupmsg(session->sd)); rc++; q=&session->contributing_sources; for (tmp=qbegin(q); !qend(q,tmp); tmp=qnext(q,mp)){ m=concatb(m,dupmsg(tmp)); rc++; } rtcp_common_header_init(rtcp,session,RTCP_SDES,rc,msgdsize(mp)); return mp; }
static mblk_t * make_rtcp_fb_generic_nack(RtpSession *session, uint16_t pid, uint16_t blp) { int size = sizeof(rtcp_common_header_t) + sizeof(rtcp_fb_header_t) + sizeof(rtcp_fb_generic_nack_fci_t); mblk_t *h = allocb(size, 0); rtcp_common_header_t *ch; rtcp_fb_header_t *fbh; rtcp_fb_generic_nack_fci_t *fci; ch = (rtcp_common_header_t *)h->b_wptr; h->b_wptr += sizeof(rtcp_common_header_t); fbh = (rtcp_fb_header_t *)h->b_wptr; h->b_wptr += sizeof(rtcp_fb_header_t); fci = (rtcp_fb_generic_nack_fci_t *)h->b_wptr; h->b_wptr += sizeof(rtcp_fb_generic_nack_fci_t); fbh->packet_sender_ssrc = htonl(rtp_session_get_send_ssrc(session)); fbh->media_source_ssrc = htonl(0); rtcp_fb_generic_nack_fci_set_pid(fci, pid); rtcp_fb_generic_nack_fci_set_blp(fci, blp); /* Fill common header */ rtcp_common_header_init(ch, session, RTCP_RTPFB, RTCP_RTPFB_NACK, msgdsize(h)); return h; }
static int rtcp_xr_header_init(uint8_t *buf, RtpSession *session, int bytes_len) { rtcp_xr_header_t *header = (rtcp_xr_header_t *)buf; rtcp_common_header_init(&header->ch, session, RTCP_XR, 0, bytes_len); header->ssrc = htonl(session->snd.ssrc); return sizeof(rtcp_xr_header_t); }