Fix RTCP BYE generation/reception code

Operate on a raw block of memory and remove all participants from
the active session that are indicated in the BYE packet by their SSRCs
This commit is contained in:
Aaro Altonen 2020-08-26 15:52:19 +03:00
parent e586a007be
commit 8f55079e62
2 changed files with 30 additions and 26 deletions

View File

@ -119,7 +119,7 @@ namespace uvg_rtp {
* Return RTP_SEND_ERROR if sending "frame" did not succeed (see socket.hh for details) */
rtp_error_t send_sdes_packet(std::vector<uvg_rtp::frame::rtcp_sdes_item>& items);
rtp_error_t send_app_packet(char *name, uint8_t subtype, size_t payload_len, uint8_t *payload);
rtp_error_t send_bye_packet(uvg_rtp::frame::rtcp_bye_frame *frame);
rtp_error_t send_bye_packet(std::vector<uint32_t> ssrcs);
/* Return the latest RTCP packet received from participant of "ssrc"
* Return nullptr if we haven't received this kind of packet or if "ssrc" doesn't exist

View File

@ -4,16 +4,13 @@
#include "rtcp.hh"
rtp_error_t uvg_rtp::rtcp::handle_bye_packet(uint8_t *frame, size_t size)
rtp_error_t uvg_rtp::rtcp::handle_bye_packet(uint8_t *packet, size_t size)
{
#if 0
(void)size;
if (!frame)
if (!packet || !size)
return RTP_INVALID_VALUE;
for (size_t i = 0; i < frame->header.count; ++i) {
uint32_t ssrc = ntohl(frame->ssrc[i]);
for (size_t i = 4; i < size; i += sizeof(uint32_t)) {
uint32_t ssrc = ntohl(*(uint32_t *)&packet[i]);
if (!is_participant(ssrc)) {
LOG_WARN("Participants 0x%x is not part of this group!", ssrc);
@ -24,39 +21,46 @@ rtp_error_t uvg_rtp::rtcp::handle_bye_packet(uint8_t *frame, size_t size)
delete participants_[ssrc];
participants_.erase(ssrc);
}
#endif
return RTP_OK;
}
rtp_error_t uvg_rtp::rtcp::send_bye_packet(uvg_rtp::frame::rtcp_bye_frame *frame)
rtp_error_t uvg_rtp::rtcp::send_bye_packet(std::vector<uint32_t> ssrcs)
{
if (!frame)
return RTP_INVALID_VALUE;
if (frame->header.count == 0) {
if (ssrcs.empty()) {
LOG_WARN("Source Count in RTCP BYE packet is 0");
}
uint16_t len = frame->header.length;
frame->header.length = htons(frame->header.length);
for (size_t i = 0; i < frame->header.count; ++i) {
frame->ssrc[i] = htonl(frame->ssrc[i]);
}
size_t frame_size;
rtp_error_t ret;
uint8_t *frame;
int ptr = 4;
for (auto& participant : participants_) {
auto p = participant.second;
frame_size = 4; /* rtcp header */
frame_size += ssrcs.size() * sizeof(uint32_t);
if ((ret = p->socket->sendto(p->address, (uint8_t *)frame, len, 0)) != RTP_OK) {
if (!(frame = new uint8_t[frame_size])) {
LOG_ERROR("Failed to allocate space for RTCP Receiver Report");
return RTP_MEMORY_ERROR;
}
memset(frame, 0, frame_size);
frame[0] = (2 << 6) | (0 << 5) | (ssrcs.size() & 0x1f);
frame[1] = uvg_rtp::frame::RTCP_FT_BYE;
for (auto& ssrc : ssrcs)
SET_NEXT_FIELD_32(frame, ptr, htonl(ssrc));
for (auto& p : participants_) {
if ((ret = p.second->socket->sendto(p.second->address, frame, frame_size, 0)) != RTP_OK) {
LOG_ERROR("sendto() failed!");
return ret;
goto end;
}
update_rtcp_bandwidth(len);
update_rtcp_bandwidth(frame_size);
}
end:
delete[] frame;
return ret;
}