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; }
/* Send a complete receiver report (RR). It uses the actual informations stored in rtcp_info. */ static void rtcp_send_rr(iptv_rtcp_info_t *info) { rtcp_rr_t report; report.ssrc = htonl(info->source_ssrc); // Fill in the extended last sequence union { uint16_t buffer[2]; uint32_t result; } join2; join2.buffer[0] = htons(info->sequence_cycle); join2.buffer[1] = htons(info->last_received_sequence); report.last_seq = join2.result; // We don't compute this for now report.fraction = 0; report.lost = -1; report.lsr = htonl(0); report.dlsr = htonl(0); // TODO: see how to put something meaningful report.jitter = htonl(12); // Build the full packet rtcp_t packet; packet.common.pt = RTCP_RR; packet.common.count = 1; // TODO : set the real length packet.common.length = htons(7); packet.r.rr.ssrc = htonl(info->my_ssrc); packet.r.rr.rr[0] = report; // Build the network packet sbuf_t network_buffer; sbuf_init(&network_buffer); rtcp_append_headers(&network_buffer, &packet); rtcp_append_rr(&network_buffer, &packet); // Send it rtcp_send(info, &network_buffer); // TODO : send also the SDES CNAME packet // Cleanup sbuf_free(&network_buffer); }
static int send_rtcp_report(struct rtcp_sess *sess) { struct mbuf *mb; int err; mb = mbuf_alloc(512); if (!mb) return ENOMEM; mb->pos = RTCP_HEADROOM; err = mk_sr(sess, mb); 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; }