diff --git a/daemon/session_manager.cpp b/daemon/session_manager.cpp index 05cbbf6..14164de 100644 --- a/daemon/session_manager.cpp +++ b/daemon/session_manager.cpp @@ -37,7 +37,6 @@ #include "utils.hpp" #include "session_manager.hpp" - static uint8_t get_codec_word_lenght(const std::string& codec) { if (codec == "L16") { return 2; @@ -492,6 +491,10 @@ std::error_code SessionManager::add_source(const StreamSource& source) { info.refclk_ptp_traceable = source.refclk_ptp_traceable; info.enabled = source.enabled; info.io = source.io; + + auto ip_addr = htonl(config_->get_ip_addr()); + info.session_id = (ip_addr << 16) + (ip_addr >> 16) + source.id; + info.session_version = info.session_id + g_session_version++; // info.m_ui32PlayOutDelay = 0; // only for Sink std::unique_lock sources_lock(sources_mutex_); @@ -531,10 +534,14 @@ std::error_code SessionManager::add_source(const StreamSource& source) { return ret; } -std::string SessionManager::get_removed_source_sdp_(uint32_t id, - uint32_t addr) const { - std::string sdp("o=- " + std::to_string(id) + " 0 IN IP4 " + - ip::address_v4(addr).to_string() + "\n"); +std::string SessionManager::get_removed_source_sdp_( + uint32_t id, + uint32_t src_addr, + uint32_t session_id, + uint32_t session_version) const { + std::string sdp("o=- " + std::to_string(session_id) + " " + + std::to_string(session_version) + " IN IP4 " + + ip::address_v4(src_addr).to_string() + "\n"); return sdp; } @@ -556,7 +563,7 @@ std::string SessionManager::get_source_sdp_(uint32_t id, // build SDP std::stringstream ss; ss << "v=0\n" - << "o=- " << static_cast(id) << " 0 IN IP4 " + << "o=- " << info.session_id << " " << info.session_version << " IN IP4 " << ip::address_v4(info.stream.m_ui32SrcIP).to_string() << "\n" << "s=" << get_node_id(config_->get_ip_addr()) << " " << info.stream.m_cName << "\n" @@ -874,14 +881,15 @@ size_t SessionManager::process_sap() { for (auto const& [id, info] : sources_) { if (info.enabled) { // retrieve current active source SDP - std::string sdp = get_source_sdp_(id, info); + auto sdp = get_source_sdp_(id, info); // compute source 16bit crc uint16_t msg_crc = crc16(reinterpret_cast(sdp.c_str()), sdp.length()); // compute source hash uint32_t msg_id_hash = (static_cast(id) << 16) + msg_crc; // add/update this source in the announced sources - announced_sources_[msg_id_hash] = info.stream.m_ui32RTCPSrcIP; + announced_sources_[msg_id_hash] = {info.stream.m_ui32RTCPSrcIP, + info.session_id, info.session_version}; // add this source to the currently active sources active_sources.insert(msg_id_hash); // remove this source from deleted sources (if present) @@ -894,11 +902,15 @@ size_t SessionManager::process_sap() { } // check for sources that are no longer announced and send deletion/s - for (auto const& [msg_id_hash, src_addr] : announced_sources_) { + for (auto const& [msg_id_hash, info] : announced_sources_) { + auto src_addr = std::get<0>(info); + auto session_id = std::get<1>(info); + auto session_version = std::get<2>(info); // check if this source is no longer announced if (active_sources.find(msg_id_hash) == active_sources.end()) { // retrieve deleted source SDP - std::string sdp = get_removed_source_sdp_(msg_id_hash >> 16, src_addr); + std::string sdp = get_removed_source_sdp_(msg_id_hash >> 16, src_addr, + session_id, session_version); // send deletion for this source sap_.deletion(static_cast(msg_id_hash), src_addr, sdp); // update amount of byte sent @@ -926,15 +938,18 @@ size_t SessionManager::process_sap() { void SessionManager::on_update_sources() { // trigger sources SDP file update - std::shared_lock sources_lock(sources_mutex_); - for (auto const& [id, info] : sources_) { + sources_mutex_.lock(); + for (auto& [id, info] : sources_) { for (auto cb : update_source_observers) { + info.session_version++; cb(id, info.stream.m_cName, get_source_sdp_(id, info)); } } + sources_mutex_.unlock(); + g_session_version++; } -void SessionManager::on_ptp_status_locked() { +void SessionManager::on_ptp_status_locked() const { // set sample rate, this may require seconds (void)driver_->set_sample_rate(driver_->get_current_sample_rate()); } @@ -1049,9 +1064,13 @@ bool SessionManager::worker() { } // at end, send deletion for all announced sources - for (auto const& [msg_id_hash, src_addr] : announced_sources_) { + for (auto const& [msg_id_hash, info] : announced_sources_) { + auto src_addr = std::get<0>(info); + auto session_id = std::get<1>(info); + auto session_version = std::get<2>(info); // retrieve deleted source SDP - std::string sdp = get_removed_source_sdp_(msg_id_hash >> 16, src_addr); + std::string sdp = get_removed_source_sdp_(msg_id_hash >> 16, src_addr, + session_id, session_version); // send deletion for this source sap_.deletion(static_cast(msg_id_hash), src_addr, sdp); } @@ -1060,4 +1079,4 @@ bool SessionManager::worker() { igmp_.leave(config_->get_ip_addr_str(), ptp_primary_mcast_addr); return true; -} \ No newline at end of file +} diff --git a/daemon/session_manager.hpp b/daemon/session_manager.hpp index 49e7a18..5e219c8 100644 --- a/daemon/session_manager.hpp +++ b/daemon/session_manager.hpp @@ -90,6 +90,8 @@ struct StreamInfo { bool sink_use_sdp{true}; std::string sink_source; std::string sink_sdp; + uint32_t session_id{0}; + uint32_t session_version{0}; }; class SessionManager { @@ -166,11 +168,14 @@ class SessionManager { void on_add_sink(const StreamSink& sink, const StreamInfo& info); void on_remove_sink(const StreamInfo& info); - void on_ptp_status_locked(); + void on_ptp_status_locked() const; void on_update_sources(); - std::string get_removed_source_sdp_(uint32_t id, uint32_t src_addr) const; + std::string get_removed_source_sdp_(uint32_t id, + uint32_t src_addr, + uint32_t session_id, + uint32_t session_version) const; std::string get_source_sdp_(uint32_t id, const StreamInfo& info) const; StreamSource get_source_(uint8_t id, const StreamInfo& info) const; StreamSink get_sink_(uint8_t id, const StreamInfo& info) const; @@ -201,7 +206,10 @@ class SessionManager { mutable std::shared_mutex sinks_mutex_; /* current announced sources */ - std::map + std::map > announced_sources_; /* number of deletions sent for a a deleted source */ @@ -218,6 +226,9 @@ class SessionManager { SAP sap_{config_->get_sap_mcast_addr()}; IGMP igmp_; + + /* used to handle session versioning */ + inline static std::atomic g_session_version{0}; }; #endif