From f4461f6dc3642da54b762c40e691206e845c770c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joni=20R=C3=A4s=C3=A4nen?= Date: Thu, 14 Jul 2022 09:30:27 +0300 Subject: [PATCH] rtcp: APP and BYE compound packets It is no longer possible to send APP packets alone as RFC 3550 does not permit this. Instead they are sent together with SR and RR as they are supposed to. --- include/uvgrtp/rtcp.hh | 17 ++++- src/rtcp.cc | 162 +++++++++++++++++++++++------------------ 2 files changed, 107 insertions(+), 72 deletions(-) diff --git a/include/uvgrtp/rtcp.hh b/include/uvgrtp/rtcp.hh index d6303e8..aa62efb 100644 --- a/include/uvgrtp/rtcp.hh +++ b/include/uvgrtp/rtcp.hh @@ -13,6 +13,7 @@ #include #include #include +#include namespace uvgrtp { @@ -72,6 +73,15 @@ namespace uvgrtp { uvgrtp::frame::rtcp_sdes_packet *sdes_frame = nullptr; uvgrtp::frame::rtcp_app_packet *app_frame = nullptr; }; + + struct rtcp_app_packet { + const char* name; + uint8_t subtype; + + size_t payload_len; + const uint8_t* payload; + }; + /// \endcond class rtcp { @@ -472,7 +482,12 @@ namespace uvgrtp { int interval_ms_; - std::vector ourItems_; + std::mutex packet_mutex_; + + // messages waiting to be sent + std::vector ourItems_; // always sent + std::vector bye_ssrcs_; // sent once + std::map> app_packets_; // sent one at a time per name uvgrtp::frame::rtcp_sdes_item cnameItem_; char cname_[255]; diff --git a/src/rtcp.cc b/src/rtcp.cc index ac3a828..37b575d 100644 --- a/src/rtcp.cc +++ b/src/rtcp.cc @@ -18,6 +18,7 @@ #include #include #include +#include /* TODO: explain these constants */ @@ -51,7 +52,9 @@ uvgrtp::rtcp::rtcp(std::shared_ptr rtp, std::string cname, int flag app_hook_f_(nullptr), app_hook_u_(nullptr), active_(false), - interval_ms_(DEFAULT_RTCP_INTERVAL_MS) + interval_ms_(DEFAULT_RTCP_INTERVAL_MS), + ourItems_(), + bye_ssrcs_(false) { clock_rate_ = rtp->get_clock_rate(); @@ -249,9 +252,17 @@ rtp_error_t uvgrtp::rtcp::set_sdes_items(const std::vector to_ignore; + + // find invalid items and check if cname is already included + for (unsigned int i = 0; i < items.size(); ++i) { - if (item.type == 1) + if (items.at(i).type == 0) + { + LOG_WARN("Invalid item type 0 found at index %lu, removing item", i); + to_ignore.insert(i); + } + else if (items.at(i).type == 1) { hasCname = true; LOG_DEBUG("Found CName in sdes items, not adding pregenerated"); @@ -265,7 +276,14 @@ rtp_error_t uvgrtp::rtcp::set_sdes_items(const std::vector ssrcs) @@ -1606,50 +1646,30 @@ rtp_error_t uvgrtp::rtcp::send_bye_packet(std::vector ssrcs) // ssrcs contains all our ssrcs which we usually have one unless we are a mixer if (ssrcs.empty()) { - LOG_WARN("Source Count in RTCP BYE packet is 0"); + LOG_WARN("Source Count in RTCP BYE packet is 0. Not sending."); } + packet_mutex_.lock(); + bye_ssrcs_ = ssrcs; + packet_mutex_.unlock(); - size_t rtcp_packet_size = get_bye_packet_size(ssrcs); - uint8_t* frame = new uint8_t[rtcp_packet_size]; - memset(frame, 0, rtcp_packet_size); - - rtp_error_t ret = RTP_OK; - int write_ptr = 0; - uint16_t secondField = (ssrcs.size() & 0x1f); - // header construction does not add our ssrc for BYE - if (!construct_rtcp_header(frame, write_ptr, rtcp_packet_size, secondField, - uvgrtp::frame::RTCP_FT_BYE) || - !construct_bye_packet(frame, write_ptr, ssrcs)) - { - delete[] frame; - return RTP_GENERIC_ERROR; - } - - // TODO: Should only be sent in a compound packet - return send_rtcp_packet_to_participants(frame, rtcp_packet_size, false); + return RTP_OK; } rtp_error_t uvgrtp::rtcp::send_app_packet(const char* name, uint8_t subtype, size_t payload_len, const uint8_t* payload) { - size_t rtcp_packet_size = get_app_packet_size(payload_len); - uint8_t* frame = new uint8_t[rtcp_packet_size]; - memset(frame, 0, rtcp_packet_size); - - int write_ptr = 0; - uint16_t secondField = (subtype & 0x1f); - - if (!construct_rtcp_header(frame, write_ptr, rtcp_packet_size, secondField, - uvgrtp::frame::RTCP_FT_APP) || - !construct_ssrc(frame, write_ptr, ssrc_) || - !construct_app_packet(frame, write_ptr, name, payload, payload_len)) + std::string str(name); + rtcp_app_packet packet = { name, subtype, payload_len, payload }; + packet_mutex_.lock(); + if (!app_packets_[name].empty()) { - delete[] frame; - return RTP_GENERIC_ERROR; + LOG_WARN("Adding a new APP packet for sending when %llu packets are waiting to be sent", + app_packets_[name].size()); } + app_packets_[name].push_back(packet); + packet_mutex_.unlock(); - // TODO: Should only be sent in compound packet - return send_rtcp_packet_to_participants(frame, rtcp_packet_size, true); + return RTP_OK; } void uvgrtp::rtcp::set_session_bandwidth(int kbps)