int test_rtcp_encode(void) { struct mbuf *mb; const size_t sz = sizeof(rtcp_msg) - 1; const uint32_t srcv[2] = {0x12345678, 0x00abcdef}; int err = 0; mb = mbuf_alloc(512); if (!mb) return ENOMEM; err |= rtcp_encode(mb, RTCP_SR, 1, 0x12345678, 0x00112233, 0x44556677, 0x22332233, 0x00001111, 0x00002222, encode_handler, 0); err |= rtcp_encode(mb, RTCP_RR, 1, 0x12345678, encode_handler, 0); err |= rtcp_encode(mb, RTCP_SDES, 1, sdes_encode_handler, 0); err |= rtcp_encode(mb, RTCP_BYE, 2, srcv, "ciao"); err |= rtcp_encode(mb, RTCP_APP, 0, 0x12345678, "name", "data", (size_t)4); err |= rtcp_encode(mb, RTCP_FIR, 0, 0x12345678); err |= rtcp_encode(mb, RTCP_NACK, 0, 0x12345678, 0x89ab, 0xcdef); err |= rtcp_encode(mb, RTCP_RTPFB, RTCP_RTPFB_GNACK, 0x12345678, 0xfedcba98, gnack_encode, 0); err |= rtcp_encode(mb, RTCP_PSFB, RTCP_PSFB_PLI, 0x12345678, 0xfedcba98, NULL, 0); err |= rtcp_encode(mb, RTCP_PSFB, RTCP_PSFB_SLI, 0x12345678, 0xfedcba98, sli_encode, 0); if (err) goto out; if (mb->end != sz) { err = EPROTO; } if (0 != memcmp(mb->buf, rtcp_msg, mb->end)) { err = EBADMSG; } if (err) { DEBUG_WARNING("encode error: %m\n", err); hexdump(stderr, mb->buf, mb->end); } mb->pos = 0; while (mbuf_get_left(mb) >= 4 && !err) { struct rtcp_msg *msg = NULL; err = rtcp_decode(&msg, mb); msg = mem_deref(msg); } if (err) goto out; /* verify that rtcp_decode() read the whole buffer */ TEST_EQUALS(mb->end, mb->pos); out: mem_deref(mb); return err; }
static int test_rtcp_decode_badmsg(void) { struct rtcp_msg *msg = NULL; uint32_t ssrc = 0xcafebabe; struct mbuf *mb; int err = 0; mb = mbuf_alloc(128); if (!mb) { err = ENOMEM; goto out; } err = rtcp_encode(mb, RTCP_PSFB, RTCP_PSFB_SLI, ssrc, ssrc, NULL, NULL); if (err) goto out; /* simulate a corrupt RTCP packet */ mb->pos = 2; (void)mbuf_write_u16(mb, htons(0)); mb->pos = 0; if (EBADMSG != rtcp_decode(&msg, mb)) { err = EBADMSG; goto out; } out: mem_deref(msg); mem_deref(mb); return err; }
static int send_bye_packet(struct rtcp_sess *sess) { const uint32_t ssrc = rtp_sess_ssrc(sess->rs); struct mbuf *mb; int err; mb = mbuf_alloc(512); if (!mb) return ENOMEM; mb->pos = RTCP_HEADROOM; err = rtcp_encode(mb, RTCP_BYE, 1, &ssrc, "Adjo"); err |= mk_sdes(sess, mb); if (err) goto out; mb->pos = RTCP_HEADROOM; err = rtcp_send(sess->rs, mb); out: mem_deref(mb); return err; }
/** Create a Sender Report */ static int mk_sr(struct rtcp_sess *sess, struct mbuf *mb) { struct ntp_time ntp = {0, 0}; struct txstat txstat; uint32_t dur = 0, rtp_ts = 0; int err; err = ntp_time_get(&ntp); if (err) return err; lock_read_get(sess->lock); txstat = sess->txstat; lock_rel(sess->lock); if (txstat.start) { dur = (uint32_t)(time(NULL) - txstat.start); rtp_ts = txstat.ts_offset + dur * sess->srate_tx; } err = rtcp_encode(mb, RTCP_SR, sess->senderc, rtp_sess_ssrc(sess->rs), ntp.hi, ntp.lo, rtp_ts, txstat.psent, txstat.osent, encode_handler, sess->members); if (err) return err; return err; }
int test_rtcp_encode_afb(void) { uint32_t ssrc_packet_sender, ssrc_media_source; const char *afb_payload = "AFB tull"; struct rtcp_msg *msg = NULL; struct mbuf *mb; int err = 0; mb = mbuf_alloc(512); if (!mb) return ENOMEM; ssrc_packet_sender = 0xbad00bad; ssrc_media_source = 0; /* always 0 */ err = rtcp_encode(mb, RTCP_PSFB, RTCP_PSFB_AFB, ssrc_packet_sender, ssrc_media_source, afb_encode_handler, afb_payload); if (err) goto out; mb->pos = 0; err = rtcp_decode(&msg, mb); if (err) goto out; if (msg->hdr.count != RTCP_PSFB_AFB) { DEBUG_WARNING("expected AFB, got fmt=%u\n", msg->hdr.count); err = EPROTO; goto out; } if (msg->r.fb.ssrc_packet != ssrc_packet_sender || msg->r.fb.ssrc_media != ssrc_media_source) { DEBUG_WARNING("error in SSRC encoding\n"); err = EBADMSG; goto out; } if (!msg->r.fb.fci.afb || mbuf_get_left(msg->r.fb.fci.afb) != strlen(afb_payload)) { DEBUG_WARNING("error in AFB mbuf (left=%u, size=%u)\n", mbuf_get_left(msg->r.fb.fci.afb), strlen(afb_payload)); err = EBADMSG; goto out; } if (0 != memcmp(mbuf_buf(msg->r.fb.fci.afb), afb_payload, strlen(afb_payload))) { DEBUG_WARNING("error in AFB mbuf content\n"); err = EBADMSG; goto out; } /* verify that rtcp_decode() read the whole buffer */ TEST_EQUALS(mb->end, mb->pos); out: mem_deref(mb); mem_deref(msg); return err; }
static int mk_sdes(struct rtcp_sess *sess, struct mbuf *mb) { return rtcp_encode(mb, RTCP_SDES, 1, sdes_encode_handler, sess); }