diff --git a/daemon/.clang-format b/daemon/.clang-format index d46c7cc..ccfd9a9 100644 --- a/daemon/.clang-format +++ b/daemon/.clang-format @@ -129,7 +129,7 @@ RawStringFormats: CanonicalDelimiter: '' BasedOnStyle: google ReflowComments: true -SortIncludes: true +SortIncludes: false SortUsingDeclarations: true SpaceAfterCStyleCast: false SpaceAfterLogicalNot: false diff --git a/daemon/browser.cpp b/daemon/browser.cpp index a90685b..e023fc6 100644 --- a/daemon/browser.cpp +++ b/daemon/browser.cpp @@ -26,46 +26,31 @@ using namespace boost::algorithm; using namespace std::chrono; using second_t = duration >; -std::shared_ptr Browser::create( - std::shared_ptr config) { +std::shared_ptr Browser::create(std::shared_ptr config) { // no need to be thread-safe here static std::weak_ptr instance; if (auto ptr = instance.lock()) { return ptr; } - auto ptr = - std::shared_ptr(new Browser(config)); + auto ptr = std::shared_ptr(new Browser(config)); instance = ptr; return ptr; } std::list Browser::get_remote_sources( - const std::string& _source) const { + const std::string& _source) const { std::list sources_list; std::shared_lock sources_lock(sources_mutex_); // return list of remote sources ordered by name - for (const auto& source: sources_.get()) { - if (boost::iequals(source.source, _source) || - boost::iequals("all", _source)) { + for (const auto& source : sources_.get()) { + if (boost::iequals(source.source, _source) || + boost::iequals("all", _source)) { sources_list.push_back(source); } } return sources_list; } -static std::string sdp_get_subject(const std::string& sdp) { - std::stringstream ssstrem(sdp); - std::string line; - while (getline(ssstrem, line, '\n')) { - if (line.substr(0, 2) == "s=") { - auto subject = line.substr(2); - trim(subject); - return subject; - } - } - return ""; -} - bool Browser::worker() { sap_.set_multicast_interface(config_->get_ip_addr_str()); // Join SAP muticast address @@ -94,49 +79,54 @@ bool Browser::worker() { // Source is not in the map if (is_announce) { // annoucement, add new source - sources_.insert({ - id, "SAP", ip::address_v4(ntohl(addr)).to_string(), - sdp_get_subject(sdp), {}, sdp, - static_cast(duration_cast(steady_clock::now() - - startup_).count()), - 360 }); + sources_.insert( + {id, + "SAP", + ip::address_v4(ntohl(addr)).to_string(), + sdp_get_subject(sdp), + {}, + sdp, + static_cast( + duration_cast(steady_clock::now() - startup_) + .count()), + 360}); } } else { // Source is already in the map if (is_announce) { BOOST_LOG_TRIVIAL(debug) - << "browser:: refreshing SAP source " << it->id; + << "browser:: refreshing SAP source " << it->id; // annoucement, update last seen and announce period - uint32_t last_seen = - duration_cast(steady_clock::now() - startup_).count(); + uint32_t last_seen = + duration_cast(steady_clock::now() - startup_).count(); auto upd_source{*it}; upd_source.announce_period = last_seen - upd_source.last_seen; upd_source.last_seen = last_seen; - sources_.replace(it, upd_source); - } else { - BOOST_LOG_TRIVIAL(info) - << "browser:: removing SAP source " << it->id - << " name " << it->name; + sources_.replace(it, upd_source); + } else { + BOOST_LOG_TRIVIAL(info) << "browser:: removing SAP source " << it->id + << " name " << it->name; // deletion, remove entry - sources_.erase(it); + sources_.erase(it); } } } // check if it's time to update the SAP remote sources - if ((duration_cast(steady_clock::now() - sap_timepoint).count()) - > sap_interval) { + if ((duration_cast(steady_clock::now() - sap_timepoint).count()) > + sap_interval) { sap_timepoint = steady_clock::now(); // remove all sessions no longer announced - auto offset = duration_cast(steady_clock::now() - startup_).count(); + auto offset = + duration_cast(steady_clock::now() - startup_).count(); std::unique_lock sources_lock(sources_mutex_); for (auto it = sources_.begin(); it != sources_.end();) { if (it->source == "SAP" && - (offset - it->last_seen) > (it->announce_period * 10)) { + (offset - it->last_seen) > (it->announce_period * 10)) { // remove from remote SAP sources BOOST_LOG_TRIVIAL(info) - << "browser:: SAP source " << it->id << " timeout"; + << "browser:: SAP source " << it->id << " timeout"; it = sources_.erase(it); } else { it++; @@ -145,31 +135,30 @@ bool Browser::worker() { } // check if it's time to process the mDNS RTSP sources - if ((duration_cast(steady_clock::now() - mdns_timepoint).count()) - > mdns_interval) { + if ((duration_cast(steady_clock::now() - mdns_timepoint) + .count()) > mdns_interval) { mdns_timepoint = steady_clock::now(); process_results(); } } - + return true; } void Browser::on_change_rtsp_source(const std::string& name, - const std::string& domain, - const RtspSource& s) { - uint32_t last_seen = duration_cast(steady_clock::now() - - startup_).count(); + const std::string& domain, + const RtspSource& s) { + uint32_t last_seen = + duration_cast(steady_clock::now() - startup_).count(); std::unique_lock sources_lock(sources_mutex_); /* search by name */ auto rng = sources_.get().equal_range(name); - while(rng.first != rng.second){ + while (rng.first != rng.second) { const auto& it = rng.first; if (it->source == "mDNS" && it->domain == domain) { /* mDNS source with same name and domain -> update */ BOOST_LOG_TRIVIAL(info) << "browser:: updating RTSP source " << s.id - << " name " << name - << " domain " << domain; + << " name " << name << " domain " << domain; auto upd_source{*it}; upd_source.id = s.id; upd_source.sdp = s.sdp; @@ -181,9 +170,8 @@ void Browser::on_change_rtsp_source(const std::string& name, ++rng.first; } /* entry not found -> add */ - BOOST_LOG_TRIVIAL(info) << "browser:: adding RTSP source " << s.id - << " name " << name - << " domain " << domain; + BOOST_LOG_TRIVIAL(info) << "browser:: adding RTSP source " << s.id << " name " + << name << " domain " << domain; sources_.insert( {s.id, s.source, s.address, name, domain, s.sdp, last_seen, 0}); } @@ -193,12 +181,12 @@ void Browser::on_remove_rtsp_source(const std::string& name, std::unique_lock sources_lock(sources_mutex_); auto& name_idx = sources_.get(); auto rng = name_idx.equal_range(name); - while(rng.first != rng.second){ + while (rng.first != rng.second) { const auto& it = rng.first; if (it->source == "mDNS" && it->domain == domain) { - BOOST_LOG_TRIVIAL(info) << "browser:: removing RTSP source " << it->id - << " name " << it->name - << " domain " << it->domain; + BOOST_LOG_TRIVIAL(info) + << "browser:: removing RTSP source " << it->id << " name " << it->name + << " domain " << it->domain; name_idx.erase(it); break; } @@ -230,4 +218,3 @@ bool Browser::terminate() { } return true; } - diff --git a/daemon/browser.hpp b/daemon/browser.hpp index b669d6f..c76d467 100644 --- a/daemon/browser.hpp +++ b/daemon/browser.hpp @@ -20,22 +20,21 @@ #ifndef _BROWSER_HPP_ #define _BROWSER_HPP_ +#include +#include +#include +#include +#include +#include #include +#include #include #include -#include -#include - -#include -#include -#include -#include -#include #include "config.hpp" -#include "sap.hpp" #include "igmp.hpp" #include "mdns_client.hpp" +#include "sap.hpp" using namespace boost::multi_index; @@ -46,54 +45,52 @@ struct RemoteSource { std::string name; std::string domain; /* mDNS only */ std::string sdp; - uint32_t last_seen{0}; /* seconds from daemon startup */ + uint32_t last_seen{0}; /* seconds from daemon startup */ uint32_t announce_period{0}; /* period between annoucements */ }; class Browser : public MDNSClient { public: - static std::shared_ptr create( - std::shared_ptr config); + static std::shared_ptr create(std::shared_ptr config); Browser() = delete; Browser(const Browser&) = delete; Browser& operator=(const Browser&) = delete; - virtual ~Browser(){ terminate(); }; + virtual ~Browser() { terminate(); }; bool init() override; bool terminate() override; std::list get_remote_sources( - const std::string& source = "all") const; + const std::string& source = "all") const; protected: // singleton, use create() to build - Browser(std::shared_ptr config): - MDNSClient(config), - startup_(std::chrono::steady_clock::now()){}; + Browser(std::shared_ptr config) + : MDNSClient(config), startup_(std::chrono::steady_clock::now()){}; bool worker(); - virtual void on_change_rtsp_source( - const std::string& name, - const std::string& domain, - const RtspSource& source) override; - virtual void on_remove_rtsp_source( - const std::string& name, - const std::string& domain) override; + virtual void on_change_rtsp_source(const std::string& name, + const std::string& domain, + const RtspSource& source) override; + virtual void on_remove_rtsp_source(const std::string& name, + const std::string& domain) override; std::future res_; std::atomic_bool running_{false}; /* current sources */ - struct id_tag{}; - using by_id = hashed_unique, member>; - struct name_tag{}; - using by_name = ordered_non_unique, member>; - using sources_t = multi_index_container>; - + struct id_tag {}; + using by_id = + hashed_unique, + member>; + struct name_tag {}; + using by_name = ordered_non_unique< + tag, + member>; + using sources_t = + multi_index_container>; + sources_t sources_; mutable std::shared_mutex sources_mutex_; diff --git a/daemon/config.cpp b/daemon/config.cpp index 8f4f316..586b368 100644 --- a/daemon/config.cpp +++ b/daemon/config.cpp @@ -17,23 +17,22 @@ // along with this program. If not, see . // +#include +#include +#include + #include #include #include #include - #include #include #include #include -#include -#include -#include - -#include "config.hpp" #include "interface.hpp" #include "json.hpp" +#include "config.hpp" using namespace boost::asio; @@ -58,8 +57,7 @@ std::shared_ptr Config::parse(const std::string& filename) { config.log_severity_ = 2; if (config.playout_delay_ > 4000) config.playout_delay_ = 4000; - if (config.tic_frame_size_at_1fs_ == 0 || - config.tic_frame_size_at_1fs_ > 192) + if (config.tic_frame_size_at_1fs_ == 0 || config.tic_frame_size_at_1fs_ > 192) config.tic_frame_size_at_1fs_ = 192; if (config.max_tic_frame_size_ < config.tic_frame_size_at_1fs_ || config.max_tic_frame_size_ > 1024) @@ -76,8 +74,8 @@ std::shared_ptr Config::parse(const std::string& filename) { config.sap_mcast_addr_ = "224.2.127.254"; } if (config.ptp_domain_ > 127) - if (config.ptp_domain_ > 127) - config.ptp_domain_ = 0; + if (config.ptp_domain_ > 127) + config.ptp_domain_ = 0; auto [mac_addr, mac_str] = get_interface_mac(config.interface_name_); if (mac_str.empty()) { diff --git a/daemon/config.hpp b/daemon/config.hpp index fc77c72..b5e1fde 100644 --- a/daemon/config.hpp +++ b/daemon/config.hpp @@ -63,7 +63,9 @@ class Config { void set_http_port(uint16_t http_port) { http_port_ = http_port; }; void set_rtsp_port(uint16_t rtsp_port) { rtsp_port_ = rtsp_port; }; - void set_http_base_dir(const std::string& http_base_dir) { http_base_dir_ = http_base_dir; }; + void set_http_base_dir(const std::string& http_base_dir) { + http_base_dir_ = http_base_dir; + }; void set_log_severity(int log_severity) { log_severity_ = log_severity; }; void set_playout_delay(uint32_t playout_delay) { playout_delay_ = playout_delay; @@ -105,9 +107,7 @@ class Config { void set_mac_addr(const std::array& mac_addr) { mac_addr_ = mac_addr; }; - void set_mdns_enabled(bool enabled) { - mdns_enabled_ = enabled; - }; + void set_mdns_enabled(bool enabled) { mdns_enabled_ = enabled; }; void set_interface_idx(int index) { interface_idx_ = index; }; private: diff --git a/daemon/driver_handler.cpp b/daemon/driver_handler.cpp index 9909756..dd6b82a 100644 --- a/daemon/driver_handler.cpp +++ b/daemon/driver_handler.cpp @@ -20,8 +20,8 @@ #include #include -#include "driver_handler.hpp" #include "log.hpp" +#include "driver_handler.hpp" /* void dump(const void* mem, unsigned int n) { @@ -107,13 +107,13 @@ bool DriverHandler::event_receiver() { if (palsa_msg->errCode == 0) { size_t res_size = sizeof(int32_t); uint8_t res[sizeof(int32_t)]; - memset(res, 0, res_size); + memset(res, 0, res_size); on_event(palsa_msg->id, res_size, res, palsa_msg->dataSize, reinterpret_cast(palsa_msg) + data_offset); BOOST_LOG_TRIVIAL(debug) << "driver_handler::sending event response " << palsa_msg->id << " data len " << res_size; - memset(response_buffer_, 0, sizeof(response_buffer_)); + memset(response_buffer_, 0, sizeof(response_buffer_)); try { send(palsa_msg->id, client_k2u_, response_buffer_, res_size, res); } catch (boost::system::error_code& ec) { @@ -183,8 +183,9 @@ void DriverHandler::send_command(enum MT_ALSA_msg_id id, << palsa_msg->errCode << " data len " << palsa_msg->dataSize; if (id != palsa_msg->id) { - BOOST_LOG_TRIVIAL(warning) << "driver_handler:: unexpected cmd response:" - << "sent " << id << " received " << palsa_msg->id; + BOOST_LOG_TRIVIAL(warning) + << "driver_handler:: unexpected cmd response:" + << "sent " << id << " received " << palsa_msg->id; on_command_error(palsa_msg->id, DaemonErrc::invalid_driver_response); } else { if (palsa_msg->errCode == 0) { diff --git a/daemon/driver_handler.hpp b/daemon/driver_handler.hpp index b6f5297..b7957f7 100644 --- a/daemon/driver_handler.hpp +++ b/daemon/driver_handler.hpp @@ -24,9 +24,9 @@ #include "MT_ALSA_message_defs.h" #include "config.hpp" +#include "error_code.hpp" #include "log.hpp" #include "netlink_client.hpp" -#include "error_code.hpp" class DriverHandler { public: @@ -40,7 +40,7 @@ class DriverHandler { DriverHandler(){}; DriverHandler(const DriverHandler&) = delete; DriverHandler& operator=(const DriverHandler&) = delete; - virtual ~DriverHandler(){ terminate(); }; + virtual ~DriverHandler() { terminate(); }; virtual bool init(const Config& config); virtual bool terminate(); @@ -76,8 +76,8 @@ class DriverHandler { uint8_t event_buffer_[buffer_size]; uint8_t response_buffer_[buffer_size]; NetlinkClient client_u2k_{"commands"}; /* u2k for commands */ - NetlinkClient client_k2u_{"events"}; /* k2u for events */ - std::mutex mutex_; /* one command at a time */ + NetlinkClient client_k2u_{"events"}; /* k2u for events */ + std::mutex mutex_; /* one command at a time */ }; #endif diff --git a/daemon/driver_manager.cpp b/daemon/driver_manager.cpp index 2604f93..9a1be6f 100644 --- a/daemon/driver_manager.cpp +++ b/daemon/driver_manager.cpp @@ -19,50 +19,45 @@ #include -#include "driver_manager.hpp" #include "log.hpp" +#include "driver_manager.hpp" -static const std::vector alsa_msg_str = { - "Start", - "Stop", - "Reset", - "StartIO", - "StopIO", - "SetSampleRate", - "GetSampleRate", - "GetAudioMode", - "SetDSDAudioMode", - "SetTICFrameSizeAt1FS", - "SetMaxTICFrameSize", - "SetNumberOfInputs", - "SetNumberOfOutputs", - "GetNumberOfInputs", - "GetNumberOfOutputs", - "SetInterfaceName", - "Add_RTPStream", - "Remove_RTPStream", - "Update_RTPStream_Name", - "GetPTPInfo", - "Hello", - "Bye", - "Ping", - "SetMasterOutputVolume", - "SetMasterOutputSwitch", - "GetMasterOutputVolume", - "GetMasterOutputSwitch", - "SetPlayoutDelay", - "SetCaptureDelay", - "GetRTPStreamStatus", - "SetPTPConfig", - "GetPTPConfig", - "GetPTPStatus" -}; +static const std::vector alsa_msg_str = {"Start", + "Stop", + "Reset", + "StartIO", + "StopIO", + "SetSampleRate", + "GetSampleRate", + "GetAudioMode", + "SetDSDAudioMode", + "SetTICFrameSizeAt1FS", + "SetMaxTICFrameSize", + "SetNumberOfInputs", + "SetNumberOfOutputs", + "GetNumberOfInputs", + "GetNumberOfOutputs", + "SetInterfaceName", + "Add_RTPStream", + "Remove_RTPStream", + "Update_RTPStream_Name", + "GetPTPInfo", + "Hello", + "Bye", + "Ping", + "SetMasterOutputVolume", + "SetMasterOutputSwitch", + "GetMasterOutputVolume", + "GetMasterOutputSwitch", + "SetPlayoutDelay", + "SetCaptureDelay", + "GetRTPStreamStatus", + "SetPTPConfig", + "GetPTPConfig", + "GetPTPStatus"}; -static const std::vector ptp_status_str = { - "unlocked", - "locking", - "locked" -}; +static const std::vector ptp_status_str = {"unlocked", "locking", + "locked"}; std::shared_ptr DriverManager::create() { // no need to be thread-safe here @@ -86,9 +81,7 @@ bool DriverManager::init(const Config& config) { ptp_config.ui8Domain = config.get_ptp_domain(); ptp_config.ui8DSCP = config.get_ptp_dscp(); - bool res = hello() || - start() || - reset() || + bool res = hello() || start() || reset() || set_interface_name(config.get_interface_name()) || set_ptp_config(ptp_config) || set_tic_frame_size_at_1fs(config.get_tic_frame_size_at_1fs()) || @@ -288,8 +281,7 @@ void DriverManager::on_event(enum MT_ALSA_msg_id id, if (req_size == sizeof(int32_t)) { memcpy(&output_volume, req, req_size); BOOST_LOG_TRIVIAL(info) - << "driver_manager:: event SetMasterOutputVolume " - << output_volume; + << "driver_manager:: event SetMasterOutputVolume " << output_volume; } resp_size = 0; break; @@ -297,15 +289,15 @@ void DriverManager::on_event(enum MT_ALSA_msg_id id, if (req_size == sizeof(int32_t)) { memcpy(&output_switch, req, req_size); BOOST_LOG_TRIVIAL(info) - << "driver_manager:: event SetMasterOutputSwitch " - << output_switch; + << "driver_manager:: event SetMasterOutputSwitch " << output_switch; } resp_size = 0; break; case MT_ALSA_Msg_SetSampleRate: if (req_size == sizeof(uint32_t)) { memcpy(&sample_rate, req, req_size); - BOOST_LOG_TRIVIAL(info) << "driver_manager:: event SetSampleRate " << sample_rate; + BOOST_LOG_TRIVIAL(info) + << "driver_manager:: event SetSampleRate " << sample_rate; } resp_size = 0; break; diff --git a/daemon/driver_manager.hpp b/daemon/driver_manager.hpp index 8c3fba7..938c2e2 100644 --- a/daemon/driver_manager.hpp +++ b/daemon/driver_manager.hpp @@ -23,10 +23,9 @@ #include #include -#include "driver_handler.hpp" - #include "RTP_stream_info.h" #include "audio_streamer_clock_PTP_defs.h" +#include "driver_handler.hpp" class DriverManager : public DriverHandler { public: diff --git a/daemon/error_code.cpp b/daemon/error_code.cpp index 7ca0ac8..ee8f7ac 100644 --- a/daemon/error_code.cpp +++ b/daemon/error_code.cpp @@ -102,7 +102,7 @@ std::string DaemonErrCategory::message(int ev) const { case DaemonErrc::cannot_retrieve_sdp: return "cannot retrieve SDP"; case DaemonErrc::cannot_parse_sdp: - return "cannot parse SDP"; + return "cannot parse SDP"; case DaemonErrc::send_invalid_size: return "send data size too big"; case DaemonErrc::send_u2k_failed: diff --git a/daemon/error_code.hpp b/daemon/error_code.hpp index 5749e25..df1ef16 100644 --- a/daemon/error_code.hpp +++ b/daemon/error_code.hpp @@ -45,18 +45,18 @@ std::error_code get_driver_error(int code); // Daemon errors enum class DaemonErrc { - invalid_stream_id = 40, // daemon invalid stream id - stream_id_in_use = 41, // daemon stream id is in use - stream_id_not_in_use = 42, // daemon stream not in use - invalid_url = 43, // daemon invalid URL - cannot_retrieve_sdp = 44, // daemon cannot retrieve SDP - cannot_parse_sdp = 45, // daemon cannot parse SDP - stream_name_in_use = 46, // daemon source or sink name in use - send_invalid_size = 50, // daemon data size too big for buffer - send_u2k_failed = 51, // daemon failed to send command to driver - send_k2u_failed = 52, // daemon failed to send event response to driver - receive_u2k_failed = 53, // daemon failed to receive response from driver - receive_k2u_failed = 54, // daemon failed to receive event from driver + invalid_stream_id = 40, // daemon invalid stream id + stream_id_in_use = 41, // daemon stream id is in use + stream_id_not_in_use = 42, // daemon stream not in use + invalid_url = 43, // daemon invalid URL + cannot_retrieve_sdp = 44, // daemon cannot retrieve SDP + cannot_parse_sdp = 45, // daemon cannot parse SDP + stream_name_in_use = 46, // daemon source or sink name in use + send_invalid_size = 50, // daemon data size too big for buffer + send_u2k_failed = 51, // daemon failed to send command to driver + send_k2u_failed = 52, // daemon failed to send event response to driver + receive_u2k_failed = 53, // daemon failed to receive response from driver + receive_k2u_failed = 54, // daemon failed to receive event from driver invalid_driver_response = 55 // unexpected driver command response code }; diff --git a/daemon/http_server.cpp b/daemon/http_server.cpp index 3530b9c..7ae6c00 100644 --- a/daemon/http_server.cpp +++ b/daemon/http_server.cpp @@ -23,14 +23,16 @@ #include #include -#include "http_server.hpp" -#include "log.hpp" #include "json.hpp" +#include "log.hpp" +#include "http_server.hpp" using namespace httplib; -static inline void set_headers(Response& res, const std::string content_type = "") { - res.set_header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); +static inline void set_headers(Response& res, + const std::string content_type = "") { + res.set_header("Access-Control-Allow-Methods", + "GET, POST, PUT, DELETE, OPTIONS"); res.set_header("Access-Control-Allow-Origin", "*"); res.set_header("Access-Control-Allow-Headers", "x-user-id"); if (!content_type.empty()) { @@ -52,26 +54,24 @@ static inline int get_http_error_status(const std::error_code& code) { return 500; } -static inline std::string get_http_error_message( - const std::error_code& code) { - std::stringstream ss;; +static inline std::string get_http_error_message(const std::error_code& code) { + std::stringstream ss; + ; ss << "(" << code.category().name() << ") " << code.message(); return ss.str(); } -static inline void set_error( - const std::error_code& code, - const std::string& message, - Response& res) { +static inline void set_error(const std::error_code& code, + const std::string& message, + Response& res) { res.status = get_http_error_status(code); set_headers(res, "text/plain"); res.body = message + " : " + get_http_error_message(code); } -static inline void set_error( - int status, - const std::string& message, - Response& res) { +static inline void set_error(int status, + const std::string& message, + Response& res) { res.status = status; set_headers(res, "text/plain"); res.body = message; @@ -85,15 +85,16 @@ bool HttpServer::init() { svr_.set_base_dir(config_->get_http_base_dir().c_str()); - svr_.Get("(/|/Config|/PTP|/Sources|/Sinks|/Browser)", [&](const Request& req, Response& res) { - std::ifstream file(config_->get_http_base_dir() + "/index.html"); - std::stringstream buffer; - buffer << file.rdbuf(); - res.set_content(buffer.str(), "text/html"); - }); + svr_.Get("(/|/Config|/PTP|/Sources|/Sinks|/Browser)", + [&](const Request& req, Response& res) { + std::ifstream file(config_->get_http_base_dir() + "/index.html"); + std::stringstream buffer; + buffer << file.rdbuf(); + res.set_content(buffer.str(), "text/html"); + }); /* allows cross-origin */ - svr_.Options("/api/(.*?)", [&](const Request & /*req*/, Response &res) { + svr_.Options("/api/(.*?)", [&](const Request& /*req*/, Response& res) { set_headers(res); }); @@ -178,43 +179,44 @@ bool HttpServer::init() { }); /* get a source SDP */ - svr_.Get("/api/source/sdp/([0-9]+)", [this](const Request& req, Response& res) { - uint32_t id; - try { - id = std::stoi(req.matches[1]); - } catch (...) { - set_error(400, "failed to convert id", res); - return; - } + svr_.Get( + "/api/source/sdp/([0-9]+)", [this](const Request& req, Response& res) { + uint32_t id; + try { + id = std::stoi(req.matches[1]); + } catch (...) { + set_error(400, "failed to convert id", res); + return; + } - auto ret = session_manager_->get_source_sdp(id, res.body); - if (ret) { - set_error(ret, "get source " + std::to_string(id) + " failed", res); - } else { - set_headers(res, "application/sdp"); - } - }); + auto ret = session_manager_->get_source_sdp(id, res.body); + if (ret) { + set_error(ret, "get source " + std::to_string(id) + " failed", res); + } else { + set_headers(res, "application/sdp"); + } + }); /* get stream status */ - svr_.Get("/api/sink/status/([0-9]+)", [this](const Request& req, - Response& res) { - uint32_t id; - try { - id = std::stoi(req.matches[1]); - } catch (...) { - set_error(400, "failed to convert id", res); - return; - } - SinkStreamStatus status; - auto ret = session_manager_->get_sink_status(id, status); - if (ret) { - set_error(ret, "failed to get sink " + std::to_string(id) + - " status", res); - } else { - set_headers(res, "application/json"); - res.body = sink_status_to_json(status); - } - }); + svr_.Get( + "/api/sink/status/([0-9]+)", [this](const Request& req, Response& res) { + uint32_t id; + try { + id = std::stoi(req.matches[1]); + } catch (...) { + set_error(400, "failed to convert id", res); + return; + } + SinkStreamStatus status; + auto ret = session_manager_->get_sink_status(id, status); + if (ret) { + set_error(ret, "failed to get sink " + std::to_string(id) + " status", + res); + } else { + set_headers(res, "application/json"); + res.body = sink_status_to_json(status); + } + }); /* add a source */ svr_.Put("/api/source/([0-9]+)", [this](const Request& req, Response& res) { @@ -222,7 +224,8 @@ bool HttpServer::init() { StreamSource source = json_to_source(req.matches[1], req.body); auto ret = session_manager_->add_source(source); if (ret) { - set_error(ret, "failed to add source " + std::to_string(source.id), res); + set_error(ret, "failed to add source " + std::to_string(source.id), + res); } else { set_headers(res); } @@ -232,21 +235,22 @@ bool HttpServer::init() { }); /* remove a source */ - svr_.Delete("/api/source/([0-9]+)", [this](const Request& req, Response& res) { - uint32_t id; - try { - id = std::stoi(req.matches[1]); - } catch (...) { - set_error(400, "failed to convert id", res); - return; - } - auto ret = session_manager_->remove_source(id); - if (ret) { - set_error(ret, "failed to remove source " + std::to_string(id), res); - } else { - set_headers(res); - } - }); + svr_.Delete( + "/api/source/([0-9]+)", [this](const Request& req, Response& res) { + uint32_t id; + try { + id = std::stoi(req.matches[1]); + } catch (...) { + set_error(400, "failed to convert id", res); + return; + } + auto ret = session_manager_->remove_source(id); + if (ret) { + set_error(ret, "failed to remove source " + std::to_string(id), res); + } else { + set_headers(res); + } + }); /* add a sink */ svr_.Put("/api/sink/([0-9]+)", [this](const Request& req, Response& res) { @@ -281,12 +285,12 @@ bool HttpServer::init() { }); /* get remote sources */ - svr_.Get("/api/browse/sources/(all|mdns|sap)", - [this](const Request& req, Response& res) { - auto const sources = browser_->get_remote_sources(req.matches[1]); - set_headers(res, "application/json"); - res.body = remote_sources_to_json(sources); - }); + svr_.Get("/api/browse/sources/(all|mdns|sap)", + [this](const Request& req, Response& res) { + auto const sources = browser_->get_remote_sources(req.matches[1]); + set_headers(res, "application/json"); + res.body = remote_sources_to_json(sources); + }); svr_.set_logger([](const Request& req, const Response& res) { if (res.status == 200) { @@ -314,7 +318,8 @@ bool HttpServer::init() { }); /* wait for HTTP server to show up */ - httplib::Client cli(config_->get_ip_addr_str().c_str(), config_->get_http_port()); + httplib::Client cli(config_->get_ip_addr_str().c_str(), + config_->get_http_port()); int retry = 3; while (retry--) { auto res = cli.Get("/api/config"); diff --git a/daemon/http_server.hpp b/daemon/http_server.hpp index 13ff59a..4741046 100644 --- a/daemon/http_server.hpp +++ b/daemon/http_server.hpp @@ -22,9 +22,9 @@ #include +#include "browser.hpp" #include "config.hpp" #include "session_manager.hpp" -#include "browser.hpp" class HttpServer { public: @@ -32,9 +32,7 @@ class HttpServer { HttpServer(std::shared_ptr session_manager, std::shared_ptr browser, std::shared_ptr config) - : session_manager_(session_manager), - browser_(browser), - config_(config) {}; + : session_manager_(session_manager), browser_(browser), config_(config){}; bool init(); bool terminate(); diff --git a/daemon/igmp.hpp b/daemon/igmp.hpp index e08ce60..e5c35d0 100644 --- a/daemon/igmp.hpp +++ b/daemon/igmp.hpp @@ -21,8 +21,9 @@ #define _IGMP_HPP_ #include -#include #include +#include + #include "log.hpp" using namespace boost::asio; @@ -38,7 +39,8 @@ class IGMP { }; bool join(const std::string& interface_ip, const std::string& mcast_ip) { - uint32_t mcast_ip_addr = ip::address_v4::from_string(mcast_ip.c_str()).to_ulong(); + uint32_t mcast_ip_addr = + ip::address_v4::from_string(mcast_ip.c_str()).to_ulong(); std::lock_guard lock(mutex); auto it = mcast_ref.find(mcast_ip_addr); @@ -61,18 +63,19 @@ class IGMP { ip::multicast::enable_loopback el_option(true); socket_.set_option(el_option, ec); if (ec) { - BOOST_LOG_TRIVIAL(error) << "igmp:: enable loopback option " - << ec.message(); + BOOST_LOG_TRIVIAL(error) + << "igmp:: enable loopback option " << ec.message(); } - BOOST_LOG_TRIVIAL(info) << "igmp:: joined multicast group " - << mcast_ip << " on " << interface_ip; + BOOST_LOG_TRIVIAL(info) << "igmp:: joined multicast group " << mcast_ip + << " on " << interface_ip; mcast_ref[mcast_ip_addr] = 1; return true; } bool leave(const std::string& interface_ip, const std::string& mcast_ip) { - uint32_t mcast_ip_addr = ip::address_v4::from_string(mcast_ip.c_str()).to_ulong(); + uint32_t mcast_ip_addr = + ip::address_v4::from_string(mcast_ip.c_str()).to_ulong(); std::lock_guard lock(mutex); auto it = mcast_ref.find(mcast_ip_addr); @@ -95,8 +98,8 @@ class IGMP { return false; } - BOOST_LOG_TRIVIAL(info) << "igmp:: left multicast group " - << mcast_ip << " on " << interface_ip; + BOOST_LOG_TRIVIAL(info) + << "igmp:: left multicast group " << mcast_ip << " on " << interface_ip; return true; } diff --git a/daemon/interface.cpp b/daemon/interface.cpp index a288226..119af68 100644 --- a/daemon/interface.cpp +++ b/daemon/interface.cpp @@ -18,8 +18,9 @@ // MIT License // -#include #include +#include + #include "log.hpp" using namespace boost::asio; @@ -79,8 +80,8 @@ std::pair, std::string> get_interface_mac( std::copy(sa, sa + 8, std::begin(mac)); char str_mac[18]; - sprintf(str_mac, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", - mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + sprintf(str_mac, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", mac[0], mac[1], mac[2], + mac[3], mac[4], mac[5]); /*BOOST_LOG_TRIVIAL(debug) << "interface " << interface_name << " MAC address " << str_mac;*/ diff --git a/daemon/json.cpp b/daemon/json.cpp index 38133b1..3f7a38f 100644 --- a/daemon/json.cpp +++ b/daemon/json.cpp @@ -20,14 +20,13 @@ #include #include #include -#include #include +#include #include -#include "json.hpp" #include "log.hpp" #include "utils.hpp" - +#include "json.hpp" static inline std::string remove_undesired_chars(const std::string& s) { std::regex html_regex("[^ A-Za-z0-9:~._/=%\()\\r\\n\\t\?#-]?"); @@ -83,20 +82,28 @@ std::string config_to_json(const Config& config) { << ",\n \"tic_frame_size_at_1fs\": " << config.get_tic_frame_size_at_1fs() << ",\n \"max_tic_frame_size\": " << config.get_max_tic_frame_size() << ",\n \"sample_rate\": " << config.get_sample_rate() - << ",\n \"rtp_mcast_base\": \"" << escape_json(config.get_rtp_mcast_base()) << "\"" + << ",\n \"rtp_mcast_base\": \"" + << escape_json(config.get_rtp_mcast_base()) << "\"" << ",\n \"rtp_port\": " << config.get_rtp_port() << ",\n \"ptp_domain\": " << unsigned(config.get_ptp_domain()) << ",\n \"ptp_dscp\": " << unsigned(config.get_ptp_dscp()) - << ",\n \"sap_mcast_addr\": \"" << escape_json(config.get_sap_mcast_addr()) << "\"" + << ",\n \"sap_mcast_addr\": \"" + << escape_json(config.get_sap_mcast_addr()) << "\"" << ",\n \"sap_interval\": " << config.get_sap_interval() - << ",\n \"syslog_proto\": \"" << escape_json(config.get_syslog_proto()) << "\"" - << ",\n \"syslog_server\": \"" << escape_json(config.get_syslog_server()) << "\"" - << ",\n \"status_file\": \"" << escape_json(config.get_status_file()) << "\"" - << ",\n \"interface_name\": \"" << escape_json(config.get_interface_name()) << "\"" + << ",\n \"syslog_proto\": \"" << escape_json(config.get_syslog_proto()) + << "\"" + << ",\n \"syslog_server\": \"" << escape_json(config.get_syslog_server()) + << "\"" + << ",\n \"status_file\": \"" << escape_json(config.get_status_file()) + << "\"" + << ",\n \"interface_name\": \"" + << escape_json(config.get_interface_name()) << "\"" << ",\n \"mdns_enabled\": " << std::boolalpha << config.get_mdns_enabled() - << ",\n \"mac_addr\": \"" << escape_json(config.get_mac_addr_str()) << "\"" + << ",\n \"mac_addr\": \"" << escape_json(config.get_mac_addr_str()) + << "\"" << ",\n \"ip_addr\": \"" << escape_json(config.get_ip_addr_str()) << "\"" - << ",\n \"node_id\": \"" << escape_json(get_node_id(config.get_ip_addr())) << "\"" + << ",\n \"node_id\": \"" << escape_json(get_node_id(config.get_ip_addr())) + << "\"" << "\n}\n"; return ss.str(); } @@ -185,7 +192,7 @@ std::string sources_to_json(const std::list& sources) { int count = 0; std::stringstream ss; ss << "{\n \"sources\": ["; - for (auto const& source: sources) { + for (auto const& source : sources) { if (count++) { ss << ", "; } @@ -199,7 +206,7 @@ std::string sinks_to_json(const std::list& sinks) { int count = 0; std::stringstream ss; ss << "{\n \"sinks\": ["; - for (auto const& sink: sinks) { + for (auto const& sink : sinks) { if (count++) { ss << ", "; } @@ -210,11 +217,11 @@ std::string sinks_to_json(const std::list& sinks) { } std::string streams_to_json(const std::list& sources, - const std::list& sinks) { + const std::list& sinks) { int count = 0; std::stringstream ss; ss << "{\n \"sources\": ["; - for (auto const& source: sources) { + for (auto const& source : sources) { if (count++) { ss << ", "; } @@ -222,7 +229,7 @@ std::string streams_to_json(const std::list& sources, } count = 0; ss << " ],\n \"sinks\": ["; - for (auto const& sink: sinks) { + for (auto const& sink : sinks) { if (count++) { ss << ", "; } @@ -251,7 +258,7 @@ std::string remote_sources_to_json(const std::list& sources) { int count = 0; std::stringstream ss; ss << "{\n \"remote_sources\": ["; - for (auto const& source: sources) { + for (auto const& source : sources) { if (count++) { ss << ", "; } @@ -272,11 +279,13 @@ Config json_to_config_(std::istream& js, Config& config) { } else if (key == "rtsp_port") { config.set_rtsp_port(val.get_value()); } else if (key == "http_base_dir") { - config.set_http_base_dir(remove_undesired_chars(val.get_value())); + config.set_http_base_dir( + remove_undesired_chars(val.get_value())); } else if (key == "log_severity") { config.set_log_severity(val.get_value()); } else if (key == "interface_name") { - config.set_interface_name(remove_undesired_chars(val.get_value())); + config.set_interface_name( + remove_undesired_chars(val.get_value())); } else if (key == "playout_delay") { config.set_playout_delay(val.get_value()); } else if (key == "tic_frame_size_at_1fs") { @@ -286,7 +295,8 @@ Config json_to_config_(std::istream& js, Config& config) { } else if (key == "sample_rate") { config.set_sample_rate(val.get_value()); } else if (key == "rtp_mcast_base") { - config.set_rtp_mcast_base(remove_undesired_chars(val.get_value())); + config.set_rtp_mcast_base( + remove_undesired_chars(val.get_value())); } else if (key == "rtp_port") { config.set_rtp_port(val.get_value()); } else if (key == "ptp_domain") { @@ -294,18 +304,22 @@ Config json_to_config_(std::istream& js, Config& config) { } else if (key == "ptp_dscp") { config.set_ptp_dscp(val.get_value()); } else if (key == "sap_mcast_addr") { - config.set_sap_mcast_addr(remove_undesired_chars(val.get_value())); + config.set_sap_mcast_addr( + remove_undesired_chars(val.get_value())); } else if (key == "sap_interval") { config.set_sap_interval(val.get_value()); } else if (key == "mdns_enabled") { config.set_mdns_enabled(val.get_value()); } else if (key == "status_file") { - config.set_status_file(remove_undesired_chars(val.get_value())); + config.set_status_file( + remove_undesired_chars(val.get_value())); } else if (key == "syslog_proto") { - config.set_syslog_proto(remove_undesired_chars(val.get_value())); + config.set_syslog_proto( + remove_undesired_chars(val.get_value())); } else if (key == "syslog_server") { - config.set_syslog_server(remove_undesired_chars(val.get_value())); - } else if (key == "mac_addr" || key == "ip_addr" || key == "node_id" ) { + config.set_syslog_server( + remove_undesired_chars(val.get_value())); + } else if (key == "mac_addr" || key == "ip_addr" || key == "node_id") { /* ignored */ } else { std::cerr << "Warning: unkown configuration option " << key @@ -331,12 +345,12 @@ Config json_to_config(std::istream& js) { return json_to_config_(js, config); } -Config json_to_config(const std::string & json, const Config& curConfig) { +Config json_to_config(const std::string& json, const Config& curConfig) { std::stringstream ss(json); return json_to_config(ss, curConfig); } -Config json_to_config(const std::string & json) { +Config json_to_config(const std::string& json) { std::stringstream ss(json); return json_to_config(ss); } @@ -441,7 +455,7 @@ PTPConfig json_to_ptp_config(const std::string& json) { return ptpConfig; } -void json_to_sources(const std::string & json, +void json_to_sources(const std::string& json, std::list& sources) { std::stringstream ss(json); return json_to_sources(ss, sources); @@ -455,7 +469,8 @@ static void parse_json_sources(boost::property_tree::ptree& pt, source.enabled = v.second.get("enabled"); source.name = v.second.get("name"); source.io = v.second.get("io"); - source.max_samples_per_packet = v.second.get("max_samples_per_packet"); + source.max_samples_per_packet = + v.second.get("max_samples_per_packet"); source.codec = v.second.get("codec"); source.ttl = v.second.get("ttl"); source.payload_type = v.second.get("payload_type"); @@ -471,8 +486,7 @@ static void parse_json_sources(boost::property_tree::ptree& pt, } } -void json_to_sources(std::istream& js, - std::list& sources) { +void json_to_sources(std::istream& js, std::list& sources) { try { boost::property_tree::ptree pt; boost::property_tree::read_json(js, pt); @@ -483,8 +497,7 @@ void json_to_sources(std::istream& js, } } -void json_to_sinks(const std::string & json, - std::list& sinks) { +void json_to_sinks(const std::string& json, std::list& sinks) { std::stringstream ss(json); return json_to_sinks(ss, sinks); } @@ -511,8 +524,7 @@ static void parse_json_sinks(boost::property_tree::ptree& pt, } } -void json_to_sinks(std::istream& js, - std::list& sinks) { +void json_to_sinks(std::istream& js, std::list& sinks) { try { boost::property_tree::ptree pt; boost::property_tree::read_json(js, pt); @@ -523,7 +535,7 @@ void json_to_sinks(std::istream& js, } } -void json_to_streams(const std::string & json, +void json_to_streams(const std::string& json, std::list& sources, std::list& sinks) { std::stringstream ss(json); @@ -543,4 +555,3 @@ void json_to_streams(std::istream& js, std::to_string(je.line()) + " :" + je.message()); } } - diff --git a/daemon/json.hpp b/daemon/json.hpp index c75214f..abf8164 100644 --- a/daemon/json.hpp +++ b/daemon/json.hpp @@ -21,8 +21,9 @@ #define _JSON_HPP_ #include -#include "session_manager.hpp" + #include "browser.hpp" +#include "session_manager.hpp" /* JSON serializers */ std::string config_to_json(const Config& config); @@ -46,14 +47,10 @@ Config json_to_config(const std::string& json); StreamSource json_to_source(const std::string& id, const std::string& json); StreamSink json_to_sink(const std::string& id, const std::string& json); PTPConfig json_to_ptp_config(const std::string& json); -void json_to_sources(std::istream& jstream, - std::list& sources); -void json_to_sources(const std::string& json, - std::list& sources); -void json_to_sinks(std::istream& jstream, - std::list& sinks); -void json_to_sinks(const std::string& json, - std::list& sinks); +void json_to_sources(std::istream& jstream, std::list& sources); +void json_to_sources(const std::string& json, std::list& sources); +void json_to_sinks(std::istream& jstream, std::list& sinks); +void json_to_sinks(const std::string& json, std::list& sinks); void json_to_streams(std::istream& jstream, std::list& sources, std::list& sinks); diff --git a/daemon/log.cpp b/daemon/log.cpp index c017f74..8b894c8 100644 --- a/daemon/log.cpp +++ b/daemon/log.cpp @@ -17,14 +17,13 @@ // along with this program. If not, see . // -#include - #include #include #include #include #include #include +#include #include "config.hpp" #include "log.hpp" @@ -37,7 +36,6 @@ namespace keywords = boost::log::keywords; using sink_t = sinks::synchronous_sink; void log_init(const Config& config) { - boost::shared_ptr core = logging::core::get(); // remove all sink in case of re-configuration @@ -84,4 +82,3 @@ void log_init(const Config& config) { core->add_sink(boost::make_shared(backend)); } } - diff --git a/daemon/main.cpp b/daemon/main.cpp index e02dfb4..1693d64 100644 --- a/daemon/main.cpp +++ b/daemon/main.cpp @@ -21,15 +21,15 @@ #include #include +#include "browser.hpp" #include "config.hpp" #include "driver_manager.hpp" #include "http_server.hpp" +#include "interface.hpp" +#include "log.hpp" #include "mdns_server.hpp" #include "rtsp_server.hpp" -#include "log.hpp" #include "session_manager.hpp" -#include "interface.hpp" -#include "browser.hpp" namespace po = boost::program_options; namespace postyle = boost::program_options::command_line_style; @@ -50,12 +50,12 @@ bool is_terminated() { int main(int argc, char* argv[]) { int rc = EXIT_SUCCESS; po::options_description desc("Options"); - desc.add_options() - ("config,c", po::value()->default_value("/etc/daemon.conf"), - "daemon configuration file") - ("interface_name,i", po::value(), "Network interface name") - ("http_port,p", po::value(), "HTTP server port") - ("help,h", "Print this help message"); + desc.add_options()( + "config,c", po::value()->default_value("/etc/daemon.conf"), + "daemon configuration file")("interface_name,i", po::value(), + "Network interface name")( + "http_port,p", po::value(), "HTTP server port")( + "help,h", "Print this help message"); int unix_style = postyle::unix_style | postyle::short_allow_next; po::variables_map vm; @@ -114,8 +114,7 @@ int main(int argc, char* argv[]) { /* start session manager */ auto session_manager = SessionManager::create(driver, config); if (session_manager == nullptr || !session_manager->init()) { - throw std::runtime_error( - std::string("SessionManager:: init failed")); + throw std::runtime_error(std::string("SessionManager:: init failed")); } /* start mDNS server */ @@ -133,10 +132,9 @@ int main(int argc, char* argv[]) { /* start browser */ auto browser = Browser::create(config); if (browser == nullptr || !browser->init()) { - throw std::runtime_error( - std::string("Browser:: init failed")); + throw std::runtime_error(std::string("Browser:: init failed")); } - + /* start http server */ HttpServer http_server(session_manager, browser, config); if (!http_server.init()) { @@ -150,10 +148,11 @@ int main(int argc, char* argv[]) { while (!is_terminated()) { auto [ip_addr, ip_str] = get_interface_ip(config->get_interface_name()); if (!ip_str.empty() && config->get_ip_addr_str() != ip_str) { - BOOST_LOG_TRIVIAL(warning) << "main:: IP address changed, restarting ..."; + BOOST_LOG_TRIVIAL(warning) + << "main:: IP address changed, restarting ..."; config->set_ip_addr_str(ip_str); config->set_ip_addr(ip_addr); - break; + break; } if (config->get_need_restart()) { @@ -169,28 +168,24 @@ int main(int argc, char* argv[]) { /* stop http server */ if (!http_server.terminate()) { - throw std::runtime_error( - std::string("HttpServer:: terminate failed")); + throw std::runtime_error(std::string("HttpServer:: terminate failed")); } /* stop browser */ if (!browser->terminate()) { - throw std::runtime_error( - std::string("Browser:: terminate failed")); + throw std::runtime_error(std::string("Browser:: terminate failed")); } /* stop rtsp server */ if (!rtsp_server.terminate()) { - throw std::runtime_error( - std::string("RtspServer:: terminate failed")); + throw std::runtime_error(std::string("RtspServer:: terminate failed")); } /* stop mDNS server */ if (config->get_mdns_enabled()) { if (!mdns_server.terminate()) { - throw std::runtime_error( - std::string("MDNServer:: terminate failed")); - } + throw std::runtime_error(std::string("MDNServer:: terminate failed")); + } } /* stop session manager */ @@ -209,7 +204,7 @@ int main(int argc, char* argv[]) { BOOST_LOG_TRIVIAL(fatal) << "main:: fatal exception error: " << e.what(); rc = EXIT_FAILURE; } - + BOOST_LOG_TRIVIAL(info) << "main:: end "; } diff --git a/daemon/main.hpp b/daemon/main.hpp index 7d1725f..f9d5e68 100644 --- a/daemon/main.hpp +++ b/daemon/main.hpp @@ -17,7 +17,6 @@ // along with this program. If not, see . // - #ifndef _MAIN_HPP_ #define _MAIN_HPP_ diff --git a/daemon/mdns_client.cpp b/daemon/mdns_client.cpp index 85b2991..96e9621 100644 --- a/daemon/mdns_client.cpp +++ b/daemon/mdns_client.cpp @@ -25,6 +25,7 @@ #include "rtsp_client.hpp" #include "mdns_client.hpp" + #ifdef _USE_AVAHI_ void MDNSClient::resolve_callback(AvahiServiceResolver* r, AvahiIfIndex interface, @@ -57,9 +58,10 @@ void MDNSClient::resolve_callback(AvahiServiceResolver* r, char addr[AVAHI_ADDRESS_STR_MAX]; if ((flags & AVAHI_LOOKUP_RESULT_LOCAL) && - (mdns.config_->get_interface_name() == "lo")) { - ::strncpy(addr, mdns.config_->get_ip_addr_str().c_str(), sizeof addr - 1); - addr[sizeof addr - 1] = 0; + (mdns.config_->get_interface_name() == "lo")) { + ::strncpy(addr, mdns.config_->get_ip_addr_str().c_str(), + sizeof addr - 1); + addr[sizeof addr - 1] = 0; } else { avahi_address_snprint(addr, sizeof(addr), address); } @@ -72,36 +74,35 @@ void MDNSClient::resolve_callback(AvahiServiceResolver* r, "wide_area: %i, " "multicast: %i, " "cached: %i", - host_name, port, addr, - !!(flags & AVAHI_LOOKUP_RESULT_LOCAL), + host_name, port, addr, !!(flags & AVAHI_LOOKUP_RESULT_LOCAL), !!(flags & AVAHI_LOOKUP_RESULT_OUR_OWN), !!(flags & AVAHI_LOOKUP_RESULT_WIDE_AREA), !!(flags & AVAHI_LOOKUP_RESULT_MULTICAST), !!(flags & AVAHI_LOOKUP_RESULT_CACHED)); BOOST_LOG_TRIVIAL(debug) << "mdns_client:: (Resolver) " << info; - /* if not on loopback interface we don't want to receive self announced sessions - * or if on loopback interface we want only local announced sessions */ - if ((!(flags & AVAHI_LOOKUP_RESULT_LOCAL) && - (mdns.config_->get_interface_name() != "lo")) || - ((flags & AVAHI_LOOKUP_RESULT_LOCAL) && - (mdns.config_->get_interface_name() == "lo"))) { + /* if not on loopback interface we don't want to receive self announced + * sessions or if on loopback interface we want only local announced + * sessions */ + if ((!(flags & AVAHI_LOOKUP_RESULT_LOCAL) && + (mdns.config_->get_interface_name() != "lo")) || + ((flags & AVAHI_LOOKUP_RESULT_LOCAL) && + (mdns.config_->get_interface_name() == "lo"))) { std::lock_guard lock(mdns.sources_res_mutex_); - /* process RTSP client in async task */ + /* process RTSP client in async task */ mdns.sources_res_.emplace_back(std::async( std::launch::async, - [&mdns, - name_ = std::forward(name), + [&mdns, name_ = std::forward(name), domain_ = std::forward(domain), addr_ = std::forward(addr), port_ = std::forward(std::to_string(port))] { - RtspClient::process( - std::bind(&MDNSClient::on_change_rtsp_source, &mdns, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3), - name_, domain_, std::string("/by-name/") + name_, - addr_, port_); + RtspClient::process( + std::bind(&MDNSClient::on_change_rtsp_source, &mdns, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3), + name_, domain_, std::string("/by-name/") + name_, addr_, + port_); })); } @@ -139,15 +140,14 @@ void MDNSClient::browse_callback(AvahiServiceBrowser* b, << " in domain " << domain; /* check if a resolver is already running for this name and domain */ if (mdns.active_resolvers.find({name, domain}) != - mdns.active_resolvers.end()) { + mdns.active_resolvers.end()) { /* if already running we don't run a new resolver */ BOOST_LOG_TRIVIAL(info) << "mdns_client:: (Browser): resolution already ongoing ..."; - } - else if (!(avahi_service_resolver_new(mdns.client_.get(), interface, - protocol, name, type, domain, - AVAHI_PROTO_UNSPEC, AVAHI_LOOKUP_NO_TXT, - resolve_callback, &mdns))) { + } else if (!(avahi_service_resolver_new( + mdns.client_.get(), interface, protocol, name, type, + domain, AVAHI_PROTO_UNSPEC, AVAHI_LOOKUP_NO_TXT, + resolve_callback, &mdns))) { BOOST_LOG_TRIVIAL(error) << "mdns_client:: " << "Failed to resolve service " << name << " : " @@ -183,34 +183,32 @@ void MDNSClient::client_callback(AvahiClient* client, /* Called whenever the client or server state changes */ switch (state) { - case AVAHI_CLIENT_FAILURE: - BOOST_LOG_TRIVIAL(fatal) << "mdns_client:: server connection failure: " - << avahi_strerror(avahi_client_errno(client)); - /* TODO reconnect if disconnected */ - avahi_threaded_poll_quit(mdns.poll_.get()); - break; - - case AVAHI_CLIENT_S_REGISTERING: - case AVAHI_CLIENT_S_RUNNING: - case AVAHI_CLIENT_S_COLLISION: - /* Create the service browser */ - mdns.sb_.reset(avahi_service_browser_new(client, - mdns.config_->get_interface_idx(), - AVAHI_PROTO_INET, - "_ravenna_session._sub._rtsp._tcp", - nullptr, {}, browse_callback, &mdns)); - if (mdns.sb_ == nullptr) { - BOOST_LOG_TRIVIAL(fatal) - << "mdns_client:: failed to create service browser: " - << avahi_strerror(avahi_client_errno(mdns.client_.get())); + case AVAHI_CLIENT_FAILURE: + BOOST_LOG_TRIVIAL(fatal) << "mdns_client:: server connection failure: " + << avahi_strerror(avahi_client_errno(client)); + /* TODO reconnect if disconnected */ avahi_threaded_poll_quit(mdns.poll_.get()); - } - break; + break; - case AVAHI_CLIENT_CONNECTING: - break; + case AVAHI_CLIENT_S_REGISTERING: + case AVAHI_CLIENT_S_RUNNING: + case AVAHI_CLIENT_S_COLLISION: + /* Create the service browser */ + mdns.sb_.reset(avahi_service_browser_new( + client, mdns.config_->get_interface_idx(), AVAHI_PROTO_INET, + "_ravenna_session._sub._rtsp._tcp", nullptr, {}, browse_callback, + &mdns)); + if (mdns.sb_ == nullptr) { + BOOST_LOG_TRIVIAL(fatal) + << "mdns_client:: failed to create service browser: " + << avahi_strerror(avahi_client_errno(mdns.client_.get())); + avahi_threaded_poll_quit(mdns.poll_.get()); + } + break; + + case AVAHI_CLIENT_CONNECTING: + break; } - } #endif diff --git a/daemon/mdns_client.hpp b/daemon/mdns_client.hpp index 5c37be3..2525ec8 100644 --- a/daemon/mdns_client.hpp +++ b/daemon/mdns_client.hpp @@ -30,16 +30,16 @@ #include #include +#include #include #include -#include #include "config.hpp" #include "rtsp_client.hpp" class MDNSClient { public: - MDNSClient(std::shared_ptr config): config_(config){}; + MDNSClient(std::shared_ptr config) : config_(config){}; MDNSClient() = delete; MDNSClient(const MDNSClient&) = delete; MDNSClient& operator=(const MDNSClient&) = delete; @@ -64,10 +64,10 @@ class MDNSClient { #ifdef _USE_AVAHI_ /* order is important here */ - std::unique_ptr - poll_{nullptr, &avahi_threaded_poll_free}; - std::unique_ptr - client_{nullptr, &avahi_client_free}; + std::unique_ptr poll_{ + nullptr, &avahi_threaded_poll_free}; + std::unique_ptr client_{ + nullptr, &avahi_client_free}; std::unique_ptr sb_{nullptr, &avahi_service_browser_free}; @@ -98,7 +98,7 @@ class MDNSClient { void* userdata); std::set > - active_resolvers; + active_resolvers; #endif }; diff --git a/daemon/mdns_server.cpp b/daemon/mdns_server.cpp index aec2432..2bf3341 100644 --- a/daemon/mdns_server.cpp +++ b/daemon/mdns_server.cpp @@ -19,14 +19,14 @@ #include -#include "mdns_server.hpp" #include "config.hpp" #include "interface.hpp" #include "log.hpp" #include "utils.hpp" +#include "mdns_server.hpp" + #ifdef _USE_AVAHI_ - struct AvahiLockGuard { AvahiLockGuard() = delete; AvahiLockGuard(AvahiThreadedPoll* poll) : poll_(poll) { @@ -323,8 +323,8 @@ bool MDNSServer::init() { session_manager_->add_source_observer( SessionManager::ObserverType::add_source, - std::bind(&MDNSServer::add_service, this, - std::placeholders::_2, std::placeholders::_3)); + std::bind(&MDNSServer::add_service, this, std::placeholders::_2, + std::placeholders::_3)); session_manager_->add_source_observer( SessionManager::ObserverType::remove_source, diff --git a/daemon/mdns_server.hpp b/daemon/mdns_server.hpp index 440acb6..0800d31 100644 --- a/daemon/mdns_server.hpp +++ b/daemon/mdns_server.hpp @@ -33,16 +33,15 @@ #include #include -#include "session_manager.hpp" #include "config.hpp" +#include "session_manager.hpp" #include "utils.hpp" class MDNSServer { public: MDNSServer(std::shared_ptr session_manager, std::shared_ptr config) - : session_manager_(session_manager), - config_(config){} + : session_manager_(session_manager), config_(config) {} MDNSServer() = delete; MDNSServer(const MDNSServer&) = delete; diff --git a/daemon/netlink.hpp b/daemon/netlink.hpp index 5afb471..cfc0fe1 100644 --- a/daemon/netlink.hpp +++ b/daemon/netlink.hpp @@ -26,7 +26,7 @@ template class nl_endpoint { private: - sockaddr_nl sockaddr {.nl_family = AF_NETLINK}; + sockaddr_nl sockaddr{.nl_family = AF_NETLINK}; public: using protocol_type = Protocol; @@ -59,7 +59,8 @@ class nl_endpoint { std::size_t size() const { return sizeof(sockaddr); } - void resize(std::size_t size) { /* nothing we can do here */ } + void resize(std::size_t size) { /* nothing we can do here */ + } std::size_t capacity() const { return sizeof(sockaddr); } }; @@ -81,7 +82,6 @@ class nl_protocol { private: int proto; - }; #endif diff --git a/daemon/netlink_client.hpp b/daemon/netlink_client.hpp index beb7438..a085bc2 100644 --- a/daemon/netlink_client.hpp +++ b/daemon/netlink_client.hpp @@ -35,7 +35,7 @@ using boost::asio::deadline_timer; class NetlinkClient { public: NetlinkClient() = delete; - NetlinkClient(const std::string & name) : name_(name) { } + NetlinkClient(const std::string& name) : name_(name) {} void init(const nl_endpoint& listen_endpoint, const nl_protocol& protocol) { @@ -45,9 +45,7 @@ class NetlinkClient { check_deadline(); } - void terminate() { - socket_.close(); - } + void terminate() { socket_.close(); } std::size_t receive(const boost::asio::mutable_buffer& buffer, boost::posix_time::time_duration timeout, @@ -79,7 +77,8 @@ class NetlinkClient { if (deadline_.expires_at() <= deadline_timer::traits_type::now()) { socket_.cancel(); deadline_.expires_at(boost::posix_time::pos_infin); - //BOOST_LOG_TRIVIAL(debug) << "netlink_client:: (" << name_ << ") timeout expired"; + // BOOST_LOG_TRIVIAL(debug) << "netlink_client:: (" << name_ << ") timeout + // expired"; } deadline_.async_wait(boost::bind(&NetlinkClient::check_deadline, this)); diff --git a/daemon/rtsp_client.cpp b/daemon/rtsp_client.cpp index e220063..9777563 100644 --- a/daemon/rtsp_client.cpp +++ b/daemon/rtsp_client.cpp @@ -44,19 +44,6 @@ struct RtspResponse { std::string body; }; -static std::string sdp_get_subject(const std::string& sdp) { - std::stringstream ssstrem(sdp); - std::string line; - while (getline(ssstrem, line, '\n')) { - if (line.substr(0, 2) == "s=") { - auto subject = line.substr(2); - trim(subject); - return subject; - } - } - return ""; -} - RtspResponse read_response(tcp::iostream& s, uint16_t max_length) { RtspResponse res; std::string header; diff --git a/daemon/rtsp_server.cpp b/daemon/rtsp_server.cpp index 7ab04ec..a35c509 100644 --- a/daemon/rtsp_server.cpp +++ b/daemon/rtsp_server.cpp @@ -15,12 +15,12 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -#include "rtsp_server.hpp" + #include "utils.hpp" +#include "rtsp_server.hpp" using boost::asio::ip::tcp; - bool RtspServer::update_source(uint8_t id, const std::string& name, const std::string& sdp) { @@ -28,12 +28,11 @@ bool RtspServer::update_source(uint8_t id, BOOST_LOG_TRIVIAL(debug) << "rtsp_server:: added source " << name; std::lock_guard lock(mutex_); for (unsigned int i = 0; i < sessions_.size(); i++) { - auto session = sessions_[i].lock(); - if (session != nullptr) { - ret |= session->announce(id, name, sdp, - config_->get_ip_addr_str(), - config_->get_rtsp_port()); - } + auto session = sessions_[i].lock(); + if (session != nullptr) { + ret |= session->announce(id, name, sdp, config_->get_ip_addr_str(), + config_->get_rtsp_port()); + } } return ret; } @@ -46,8 +45,8 @@ void RtspServer::accept() { unsigned int i = 0; for (; i < sessions_.size(); i++) { if (sessions_[i].use_count() == 0) { - auto session = std::make_shared(config_, - session_manager_, std::move(socket_)); + auto session = std::make_shared( + config_, session_manager_, std::move(socket_)); sessions_[i] = session; sessions_start_point_[i] = steady_clock::now(); session->start(); @@ -72,24 +71,26 @@ bool RtspSession::announce(uint8_t id, const std::string& address, uint16_t port) { /* if a describe request is currently not beeing process - * and the specified source id has been described on this session send update */ + * and the specified source id has been described on this session send update + */ if (cseq_ < 0 && source_ids_.find(id) != source_ids_.end()) { - std::string path(std::string("/by-name/") + - get_node_id(config_->get_ip_addr()) + " " + name); + std::string path(std::string("/by-name/") + + get_node_id(config_->get_ip_addr()) + " " + name); std::stringstream ss; ss << "ANNOUNCE rtsp://" << address << ":" << std::to_string(port) << httplib::detail::encode_url(path) << " RTSP/1.0\r\n" << "User-Agent: aes67-daemon\r\n" - << "connection: Keep-Alive" << "\r\n" + << "connection: Keep-Alive" + << "\r\n" << "CSeq: " << announce_cseq_++ << "\r\n" << "Content-Length: " << sdp.length() << "\r\n" << "Content-Type: application/sdp\r\n" << "\r\n" << sdp; - BOOST_LOG_TRIVIAL(info) - << "rtsp_server:: " << "ANNOUNCE for source " << name << " sent to " - << socket_.remote_endpoint(); + BOOST_LOG_TRIVIAL(info) << "rtsp_server:: " + << "ANNOUNCE for source " << name << " sent to " + << socket_.remote_endpoint(); send_response(ss.str()); return true; @@ -97,7 +98,6 @@ bool RtspSession::announce(uint8_t id, return false; } - bool RtspSession::process_request() { /* DESCRIBE rtsp://127.0.0.1:8080/by-name/test RTSP/1.0 @@ -142,7 +142,7 @@ bool RtspSession::process_request() { if (!is_end) { return false; } - + if (fields[0].substr(0, 5) == "RTSP/") { /* we received a response, step to next request*/ return true; @@ -172,8 +172,8 @@ void RtspSession::build_response(const std::string& url) { return; } auto path = std::get<4>(res); - auto base_path = std::string("/by-name/") + - get_node_id(config_->get_ip_addr()) + " "; + auto base_path = + std::string("/by-name/") + get_node_id(config_->get_ip_addr()) + " "; uint8_t id = SessionManager::stream_id_max + 1; if (path.rfind(base_path) != std::string::npos) { /* extract the source name from path and retrive the id */ diff --git a/daemon/rtsp_server.hpp b/daemon/rtsp_server.hpp index 8f60890..52fb232 100644 --- a/daemon/rtsp_server.hpp +++ b/daemon/rtsp_server.hpp @@ -83,7 +83,8 @@ class RtspSession : public std::enable_shared_from_this { class RtspServer { public: - constexpr static uint8_t session_num_max{(SessionManager::stream_id_max + 1) * 2}; + constexpr static uint8_t session_num_max{(SessionManager::stream_id_max + 1) * + 2}; RtspServer() = delete; RtspServer(std::shared_ptr session_manager, @@ -101,21 +102,17 @@ class RtspServer { bool init() { accept(); /* start rtsp server on a separate thread */ - res_ = std::async([this](){ io_service_.run(); }); + res_ = std::async([this]() { io_service_.run(); }); session_manager_->add_source_observer( - SessionManager::ObserverType::add_source, - std::bind(&RtspServer::update_source, this, - std::placeholders::_1, - std::placeholders::_2, - std::placeholders::_3)); + SessionManager::ObserverType::add_source, + std::bind(&RtspServer::update_source, this, std::placeholders::_1, + std::placeholders::_2, std::placeholders::_3)); session_manager_->add_source_observer( - SessionManager::ObserverType::update_source, - std::bind(&RtspServer::update_source, this, - std::placeholders::_1, - std::placeholders::_2, - std::placeholders::_3)); + SessionManager::ObserverType::update_source, + std::bind(&RtspServer::update_source, this, std::placeholders::_1, + std::placeholders::_2, std::placeholders::_3)); return true; } @@ -129,7 +126,9 @@ class RtspServer { private: /* a source was updated */ - bool update_source(uint8_t id, const std::string& name, const std::string& sdp); + bool update_source(uint8_t id, + const std::string& name, + const std::string& sdp); void accept(); std::mutex mutex_; diff --git a/daemon/sap.cpp b/daemon/sap.cpp index b886191..579d81e 100644 --- a/daemon/sap.cpp +++ b/daemon/sap.cpp @@ -18,17 +18,16 @@ // #include -#include "sap.hpp" +#include "sap.hpp" using namespace boost::asio; using namespace boost::asio::ip; - -SAP::SAP(const std::string& sap_mcast_addr) : - addr_(sap_mcast_addr) +SAP::SAP(const std::string& sap_mcast_addr) + : addr_(sap_mcast_addr) // remote_endpoint_(ip::address::from_string(addr_), port) -{ +{ socket_.open(boost::asio::ip::udp::v4()); socket_.set_option(udp::socket::reuse_address(true)); socket_.bind(listen_endpoint_); @@ -92,9 +91,8 @@ bool SAP::receive(bool& is_announce, io_service_.run_one(); } while (ec == boost::asio::error::would_block); - if (!ec && length > 4 && (buffer[0] == 0x20 || buffer[0] == 0x24)) { - // only accept SAP announce or delete v2 with IPv4 + // only accept SAP announce or delete v2 with IPv4 // no reserved, no compress, no encryption // and content/type = application/sdp is_announce = (buffer[0] == 0x20); @@ -125,7 +123,7 @@ void SAP::check_deadline() { // cancel receive operation socket_.cancel(); deadline_.expires_at(boost::posix_time::pos_infin); - //BOOST_LOG_TRIVIAL(debug) << "SAP:: timeout expired when receiving"; + // BOOST_LOG_TRIVIAL(debug) << "SAP:: timeout expired when receiving"; } deadline_.async_wait(boost::bind(&SAP::check_deadline, this)); diff --git a/daemon/sap.hpp b/daemon/sap.hpp index 330bd4c..934d738 100644 --- a/daemon/sap.hpp +++ b/daemon/sap.hpp @@ -21,6 +21,7 @@ #define _SAP_HPP_ #include + #include "log.hpp" using namespace boost::asio; diff --git a/daemon/session_manager.cpp b/daemon/session_manager.cpp index 6e5ed00..620d80e 100644 --- a/daemon/session_manager.cpp +++ b/daemon/session_manager.cpp @@ -17,25 +17,26 @@ // along with this program. If not, see . // -#define CPPHTTPLIB_PAYLOAD_MAX_LENGTH 4096 //max for SDP file +#define CPPHTTPLIB_PAYLOAD_MAX_LENGTH 4096 // max for SDP file #define CPPHTTPLIB_READ_TIMEOUT_SECOND 10 + #include + #include #include #include #include -#include +#include #include #include -#include #include #include #include "json.hpp" #include "log.hpp" -#include "session_manager.hpp" -#include "utils.hpp" #include "rtsp_client.hpp" +#include "utils.hpp" +#include "session_manager.hpp" static uint8_t get_codec_word_lenght(const std::string& codec) { @@ -222,8 +223,8 @@ bool SessionManager::parse_sdp(const std::string sdp, StreamInfo& info) const { /* c=IN IP4 239.1.0.12/15 */ /* connection info of audio media */ if (status == sdp_parser_status::media || - /* generic connection info */ - status == sdp_parser_status::init) { + /* generic connection info */ + status == sdp_parser_status::init) { std::vector fields; boost::split(fields, val, [line](char c) { return c == ' ' || c == '/'; }); @@ -324,35 +325,31 @@ std::list SessionManager::get_sources() const { StreamSource SessionManager::get_source_(uint8_t id, const StreamInfo& info) const { - return { - id, - info.enabled, - info.stream.m_cName, - info.io, - info.stream.m_ui32MaxSamplesPerPacket, - info.stream.m_cCodec, - info.stream.m_byTTL, - info.stream.m_byPayloadType, - info.stream.m_ucDSCP, - info.refclk_ptp_traceable, - { info.stream.m_aui32Routing, info.stream.m_aui32Routing + - info.stream.m_byNbOfChannels } - }; + return {id, + info.enabled, + info.stream.m_cName, + info.io, + info.stream.m_ui32MaxSamplesPerPacket, + info.stream.m_cCodec, + info.stream.m_byTTL, + info.stream.m_byPayloadType, + info.stream.m_ucDSCP, + info.refclk_ptp_traceable, + {info.stream.m_aui32Routing, + info.stream.m_aui32Routing + info.stream.m_byNbOfChannels}}; } StreamSink SessionManager::get_sink_(uint8_t id, const StreamInfo& info) const { - return { - id, - info.stream.m_cName, - info.io, - info.sink_use_sdp, - info.sink_source, - info.sink_sdp, - info.stream.m_ui32PlayOutDelay, - info.ignore_refclk_gmid, - { info.stream.m_aui32Routing, info.stream.m_aui32Routing + - info.stream.m_byNbOfChannels } - }; + return {id, + info.stream.m_cName, + info.io, + info.sink_use_sdp, + info.sink_source, + info.sink_sdp, + info.stream.m_ui32PlayOutDelay, + info.ignore_refclk_gmid, + {info.stream.m_aui32Routing, + info.stream.m_aui32Routing + info.stream.m_byNbOfChannels}}; } bool SessionManager::load_status() { @@ -362,8 +359,8 @@ bool SessionManager::load_status() { std::ifstream jsonstream(config_->get_status_file()); if (!jsonstream) { - BOOST_LOG_TRIVIAL(fatal) - << "session_manager:: cannot load status file " << config_->get_status_file(); + BOOST_LOG_TRIVIAL(fatal) << "session_manager:: cannot load status file " + << config_->get_status_file(); return false; } @@ -409,10 +406,12 @@ static std::array get_mcast_mac_addr(uint32_t mcast_ip) { // As defined by IANA, the most significant 24 bits of an IPv4 multicast // MAC address are 0x01005E. // Bit 25 is 0, and the other 23 bits are the // least significant 23 bits of an IPv4 multicast address. - return { 0x01, 0x00, 0x5e, - static_cast((mcast_ip >> 16) & 0x7F), - static_cast(mcast_ip >> 8), - static_cast(mcast_ip) }; + return {0x01, + 0x00, + 0x5e, + static_cast((mcast_ip >> 16) & 0x7F), + static_cast(mcast_ip >> 8), + static_cast(mcast_ip)}; } uint8_t SessionManager::get_source_id(const std::string& name) const { @@ -421,21 +420,21 @@ uint8_t SessionManager::get_source_id(const std::string& name) const { } void SessionManager::add_source_observer(ObserverType type, Observer cb) { - switch(type) { - case ObserverType::add_source: - add_source_observers.push_back(cb); - break; - case ObserverType::remove_source: - remove_source_observers.push_back(cb); - break; - case ObserverType::update_source: - update_source_observers.push_back(cb); - break; + switch (type) { + case ObserverType::add_source: + add_source_observers.push_back(cb); + break; + case ObserverType::remove_source: + remove_source_observers.push_back(cb); + break; + case ObserverType::update_source: + update_source_observers.push_back(cb); + break; } } -void SessionManager::on_add_source(const StreamSource& source, - const StreamInfo& info) { +void SessionManager::on_add_source(const StreamSource& source, + const StreamInfo& info) { for (auto cb : add_source_observers) { cb(source.id, source.name, get_source_sdp_(source.id, info)); } @@ -449,7 +448,7 @@ void SessionManager::on_remove_source(const StreamInfo& info) { cb(info.stream.m_uiId, info.stream.m_cName, {}); } igmp_.leave(config_->get_ip_addr_str(), - ip::address_v4(info.stream.m_ui32DestIP).to_string()); + ip::address_v4(info.stream.m_ui32DestIP).to_string()); source_names_.erase(info.stream.m_cName); } @@ -462,11 +461,11 @@ std::error_code SessionManager::add_source(const StreamSource& source) { StreamInfo info; memset(&info.stream, 0, sizeof info.stream); - info.stream.m_bSource = 1; // source + info.stream.m_bSource = 1; // source info.stream.m_ui32CRTP_stream_info_sizeof = sizeof(info.stream); strncpy(info.stream.m_cName, source.name.c_str(), sizeof(info.stream.m_cName) - 1); - info.stream.m_ucDSCP = source.dscp; // IPv4 DSCP + info.stream.m_ucDSCP = source.dscp; // IPv4 DSCP info.stream.m_byTTL = source.ttl; info.stream.m_byPayloadType = source.payload_type; info.stream.m_byWordLength = get_codec_word_lenght(source.codec); @@ -474,16 +473,18 @@ std::error_code SessionManager::add_source(const StreamSource& source) { strncpy(info.stream.m_cCodec, source.codec.c_str(), sizeof(info.stream.m_cCodec) - 1); info.stream.m_ui32MaxSamplesPerPacket = source.max_samples_per_packet; - info.stream.m_ui32SamplingRate = driver_->get_current_sample_rate(); // last set from driver or config + info.stream.m_ui32SamplingRate = + driver_->get_current_sample_rate(); // last set from driver or config info.stream.m_uiId = source.id; info.stream.m_ui32RTCPSrcIP = config_->get_ip_addr(); info.stream.m_ui32SrcIP = config_->get_ip_addr(); // only for Source info.stream.m_ui32DestIP = - ip::address_v4::from_string(config_->get_rtp_mcast_base().c_str()).to_ulong() + + ip::address_v4::from_string(config_->get_rtp_mcast_base().c_str()) + .to_ulong() + source.id; info.stream.m_usSrcPort = config_->get_rtp_port(); info.stream.m_usDestPort = config_->get_rtp_port(); - info.stream.m_ui32SSRC = rand() % 65536; // use random number + info.stream.m_ui32SSRC = rand() % 65536; // use random number std::copy(source.map.begin(), source.map.end(), info.stream.m_aui32Routing); auto mcast_mac_addr = get_mcast_mac_addr(info.stream.m_ui32DestIP); std::copy(std::begin(mcast_mac_addr), std::end(mcast_mac_addr), @@ -497,16 +498,17 @@ std::error_code SessionManager::add_source(const StreamSource& source) { std::unique_lock sources_lock(sources_mutex_); auto const it = sources_.find(source.id); if (it != sources_.end()) { - BOOST_LOG_TRIVIAL(info) << "session_manager:: source id " - << std::to_string(source.id) << " is in use, updating"; + BOOST_LOG_TRIVIAL(info) + << "session_manager:: source id " << std::to_string(source.id) + << " is in use, updating"; // remove previous stream if enabled if ((*it).second.enabled) { (void)driver_->remove_rtp_stream((*it).second.handle); on_remove_source((*it).second); } } else if (source_names_.find(source.name) != source_names_.end()) { - BOOST_LOG_TRIVIAL(error) << "session_manager:: source name " - << source.name << " is in use"; + BOOST_LOG_TRIVIAL(error) + << "session_manager:: source name " << source.name << " is in use"; return DaemonErrc::stream_name_in_use; } @@ -522,8 +524,8 @@ std::error_code SessionManager::add_source(const StreamSource& source) { } on_add_source(source, info); } - - // update source map + + // update source map sources_[source.id] = info; BOOST_LOG_TRIVIAL(info) << "session_manager:: added source " << std::to_string(source.id) << " " << info.handle; @@ -542,14 +544,14 @@ std::string SessionManager::get_source_sdp_(uint32_t id, std::shared_lock ptp_lock(ptp_mutex_); uint32_t sample_rate = driver_->get_current_sample_rate(); - // need a 12 digit precision for ptime + // need a 12 digit precision for ptime std::ostringstream ss_ptime; ss_ptime.precision(12); ss_ptime << std::fixed - << static_cast(info.stream.m_ui32MaxSamplesPerPacket) * 1000 / - static_cast(sample_rate); + << static_cast(info.stream.m_ui32MaxSamplesPerPacket) * + 1000 / static_cast(sample_rate); std::string ptime = ss_ptime.str(); - // remove trailing zeros or dot + // remove trailing zeros or dot ptime.erase(ptime.find_last_not_of("0.") + 1, std::string::npos); // build SDP @@ -635,8 +637,8 @@ uint8_t SessionManager::get_sink_id(const std::string& name) const { return it != sink_names_.end() ? it->second : (stream_id_max + 1); } -void SessionManager::on_add_sink(const StreamSink& sink, - const StreamInfo& info) { +void SessionManager::on_add_sink(const StreamSink& sink, + const StreamInfo& info) { igmp_.join(config_->get_ip_addr_str(), ip::address_v4(info.stream.m_ui32DestIP).to_string()); sink_names_[sink.name] = sink.id; @@ -644,7 +646,7 @@ void SessionManager::on_add_sink(const StreamSink& sink, void SessionManager::on_remove_sink(const StreamInfo& info) { igmp_.leave(config_->get_ip_addr_str(), - ip::address_v4(info.stream.m_ui32DestIP).to_string()); + ip::address_v4(info.stream.m_ui32DestIP).to_string()); sink_names_.erase(info.stream.m_cName); } @@ -657,7 +659,7 @@ std::error_code SessionManager::add_sink(const StreamSink& sink) { StreamInfo info; memset(&info.stream, 0, sizeof info.stream); - info.stream.m_bSource = 0; // sink + info.stream.m_bSource = 0; // sink info.stream.m_ui32CRTP_stream_info_sizeof = sizeof(info.stream); strncpy(info.stream.m_cName, sink.name.c_str(), sizeof(info.stream.m_cName) - 1); @@ -704,9 +706,9 @@ std::error_code SessionManager::add_sink(const StreamSink& sink) { } sdp = std::move(res.second.sdp); } else { - BOOST_LOG_TRIVIAL(error) - << "session_manager:: unsupported protocol in URL " << sink.source; - return DaemonErrc::invalid_url; + BOOST_LOG_TRIVIAL(error) + << "session_manager:: unsupported protocol in URL " << sink.source; + return DaemonErrc::invalid_url; } BOOST_LOG_TRIVIAL(info) @@ -719,8 +721,8 @@ std::error_code SessionManager::add_sink(const StreamSink& sink) { info.sink_sdp = std::move(sdp); } else { - BOOST_LOG_TRIVIAL(info) << "session_manager:: using SDP " - << std::endl << sink.sdp; + BOOST_LOG_TRIVIAL(info) << "session_manager:: using SDP " << std::endl + << sink.sdp; if (!parse_sdp(sink.sdp, info)) { return DaemonErrc::cannot_parse_sdp; } @@ -728,18 +730,18 @@ std::error_code SessionManager::add_sink(const StreamSink& sink) { info.sink_sdp = std::move(sink.sdp); } info.sink_source = sink.source; - info.sink_use_sdp = true; // save back and use with SDP file + info.sink_use_sdp = true; // save back and use with SDP file info.stream.m_ui32FrameSize = info.stream.m_ui32MaxSamplesPerPacket; if (!info.stream.m_ui32FrameSize) { // if not from SDP use config info.stream.m_ui32FrameSize = config_->get_max_tic_frame_size(); } - - BOOST_LOG_TRIVIAL(info) << "session_manager:: sink frame size " << - info.stream.m_ui32FrameSize; - BOOST_LOG_TRIVIAL(info) << "session_manager:: playout delay " << - info.stream.m_ui32PlayOutDelay; + + BOOST_LOG_TRIVIAL(info) << "session_manager:: sink frame size " + << info.stream.m_ui32FrameSize; + BOOST_LOG_TRIVIAL(info) << "session_manager:: playout delay " + << info.stream.m_ui32PlayOutDelay; auto mcast_mac_addr = get_mcast_mac_addr(info.stream.m_ui32DestIP); std::copy(std::begin(mcast_mac_addr), std::end(mcast_mac_addr), @@ -748,14 +750,15 @@ std::error_code SessionManager::add_sink(const StreamSink& sink) { std::unique_lock sinks_lock(sinks_mutex_); auto const it = sinks_.find(sink.id); if (it != sinks_.end()) { - BOOST_LOG_TRIVIAL(info) << "session_manager:: sink id " - << std::to_string(sink.id) << " is in use, updating"; + BOOST_LOG_TRIVIAL(info) + << "session_manager:: sink id " << std::to_string(sink.id) + << " is in use, updating"; // remove previous stream (void)driver_->remove_rtp_stream((*it).second.handle); on_remove_sink((*it).second); } else if (sink_names_.find(sink.name) != sink_names_.end()) { - BOOST_LOG_TRIVIAL(error) << "session_manager:: sink name " - << sink.name << " is in use"; + BOOST_LOG_TRIVIAL(error) + << "session_manager:: sink name " << sink.name << " is in use"; return DaemonErrc::stream_name_in_use; } @@ -892,8 +895,7 @@ 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_) { // check if this source is no longer announced - if (active_sources.find(msg_id_hash) == - active_sources.end()) { + 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); // send deletion for this source @@ -907,7 +909,7 @@ size_t SessionManager::process_sap() { // remove all deleted sources announced SAP::max_deletions times std::experimental::erase_if(announced_sources_, [this](auto source) { - const auto &msg_id_hash = source.first; + const auto& msg_id_hash = source.first; if (this->deleted_sources_count_[msg_id_hash] >= SAP::max_deletions) { // remove from deleted sources @@ -924,7 +926,7 @@ 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_) { + for (auto const& [id, info] : sources_) { for (auto cb : update_source_observers) { cb(id, info.stream.m_cName, get_source_sdp_(id, info)); } @@ -937,7 +939,7 @@ void SessionManager::on_ptp_status_locked() { } using namespace std::chrono; -using second_t = duration >; +using second_t = duration >; bool SessionManager::worker() { TPTPConfig ptp_config; @@ -955,8 +957,8 @@ bool SessionManager::worker() { while (running_) { // check if it's time to update the PTP status - if ((duration_cast(steady_clock::now() - ptp_timepoint).count()) - > ptp_interval) { + if ((duration_cast(steady_clock::now() - ptp_timepoint).count()) > + ptp_interval) { ptp_timepoint = steady_clock::now(); if (driver_->get_ptp_config(ptp_config) || driver_->get_ptp_status(ptp_status)) { @@ -965,21 +967,21 @@ bool SessionManager::worker() { // return false; } else { char ptp_clock_id[24]; - uint8_t* pui64GMID = reinterpret_cast(&ptp_status.ui64GMID); + uint8_t* pui64GMID = reinterpret_cast(&ptp_status.ui64GMID); snprintf(ptp_clock_id, sizeof(ptp_clock_id), - "%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X", - pui64GMID[0], pui64GMID[1], pui64GMID[2], pui64GMID[3], - pui64GMID[4], pui64GMID[5], pui64GMID[6], pui64GMID[7]); + "%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X", pui64GMID[0], + pui64GMID[1], pui64GMID[2], pui64GMID[3], pui64GMID[4], + pui64GMID[5], pui64GMID[6], pui64GMID[7]); - bool ptp_changed_gmid = false; - bool ptp_changed_to_locked = false; + bool ptp_changed_gmid = false; + bool ptp_changed_to_locked = false; // update PTP clock status - ptp_mutex_.lock(); - // update status - if (ptp_status_.gmid != ptp_clock_id) { + ptp_mutex_.lock(); + // update status + if (ptp_status_.gmid != ptp_clock_id) { ptp_status_.gmid = ptp_clock_id; ptp_changed_gmid = true; - } + } ptp_status_.jitter = ptp_status.i32Jitter; std::string new_ptp_status; switch (ptp_status.nPTPLockStatus) { @@ -999,31 +1001,30 @@ bool SessionManager::worker() { << "session_manager:: new PTP clock status " << new_ptp_status; ptp_status_.status = new_ptp_status; if (new_ptp_status == "locked") { - ptp_changed_to_locked = true; - } - } + ptp_changed_to_locked = true; + } + } // end update PTP clock status - ptp_mutex_.unlock(); + ptp_mutex_.unlock(); - - if (ptp_changed_to_locked) { + if (ptp_changed_to_locked) { on_ptp_status_locked(); - } + } - if (ptp_changed_gmid || - sample_rate != driver_->get_current_sample_rate()) { - /* master clock id changed or sample rate changed + if (ptp_changed_gmid || + sample_rate != driver_->get_current_sample_rate()) { + /* master clock id changed or sample rate changed * we need to update all the sources */ sample_rate = driver_->get_current_sample_rate(); - on_update_sources(); - } + on_update_sources(); + } } ptp_interval = 10; } // check if it's time to send sap announcements - if ((duration_cast(steady_clock::now() - sap_timepoint).count()) - > sap_interval) { + if ((duration_cast(steady_clock::now() - sap_timepoint).count()) > + sap_interval) { sap_timepoint = steady_clock::now(); auto sdp_len_sum = process_sap(); @@ -1036,7 +1037,7 @@ bool SessionManager::worker() { sap_interval = std::max(static_cast(SAP::min_interval), sdp_len_sum * 8 / SAP::bandwidth_limit); sap_interval += - (std::rand() % (sap_interval * 2 / 3)) - (sap_interval / 3); + (std::rand() % (sap_interval * 2 / 3)) - (sap_interval / 3); } BOOST_LOG_TRIVIAL(info) << "session_manager:: next SAP announcements in " @@ -1058,4 +1059,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 cd3dc98..49e7a18 100644 --- a/daemon/session_manager.hpp +++ b/daemon/session_manager.hpp @@ -21,10 +21,10 @@ #define _SESSION_MANAGER_HPP_ #include +#include #include #include #include -#include #include "config.hpp" #include "driver_manager.hpp" @@ -102,7 +102,7 @@ class SessionManager { SessionManager() = delete; SessionManager(const SessionManager&) = delete; SessionManager& operator=(const SessionManager&) = delete; - virtual ~SessionManager(){ terminate(); }; + virtual ~SessionManager() { terminate(); }; // session manager interface bool init() { @@ -135,9 +135,9 @@ class SessionManager { std::error_code remove_source(uint32_t id); uint8_t get_source_id(const std::string& name) const; - enum class ObserverType{ add_source, remove_source, update_source }; - using Observer = std::function; + enum class ObserverType { add_source, remove_source, update_source }; + using Observer = std::function< + bool(uint8_t id, const std::string& name, const std::string& sdp)>; void add_source_observer(ObserverType type, Observer cb); std::error_code add_sink(const StreamSink& sink); @@ -180,7 +180,7 @@ class SessionManager { // singleton, use create() to build SessionManager(std::shared_ptr driver, std::shared_ptr config) - : driver_(driver), config_(config){ + : driver_(driver), config_(config) { ptp_config_.domain = config->get_ptp_domain(); ptp_config_.dscp = config->get_ptp_dscp(); }; @@ -205,7 +205,7 @@ class SessionManager { announced_sources_; /* number of deletions sent for a a deleted source */ - std::unordered_map + std::unordered_map deleted_sources_count_; PTPConfig ptp_config_; diff --git a/daemon/tests/daemon.conf b/daemon/tests/daemon.conf index 886de29..9ab940d 100644 --- a/daemon/tests/daemon.conf +++ b/daemon/tests/daemon.conf @@ -20,5 +20,5 @@ "mdns_enabled": true, "mac_addr": "00:00:00:00:00:00", "ip_addr": "127.0.0.1", - "node_id": "AES67 daemon d9aca383" + "node_id": "AES67 daemon 007f0100" } diff --git a/daemon/tests/daemon_test.cpp b/daemon/tests/daemon_test.cpp index 7edf11a..c8c8bd7 100644 --- a/daemon/tests/daemon_test.cpp +++ b/daemon/tests/daemon_test.cpp @@ -17,7 +17,7 @@ // along with this program. If not, see . // -#define CPPHTTPLIB_PAYLOAD_MAX_LENGTH 4096 //max for SDP file +#define CPPHTTPLIB_PAYLOAD_MAX_LENGTH 4096 // max for SDP file #define CPPHTTPLIB_READ_TIMEOUT_SECOND 30 #include #include @@ -33,7 +33,7 @@ #define BOOST_TEST_MODULE DaemonTest #include -#if ! (defined (__arm__) || defined (__arm64__)) +#if !(defined(__arm__) || defined(__arm64__)) //#define _MEMORY_CHECK_ #endif @@ -79,17 +79,12 @@ struct DaemonInstance { static bool is_ok() { return ok; } private: - child daemon_{ + child daemon_ { #if defined _MEMORY_CHECK_ - search_path("valgrind"), + search_path("valgrind"), #endif - "../aes67-daemon", - "-c", - "daemon.conf", - "-p", - "9999", - "-i", - "lo"}; + "../aes67-daemon", "-c", "daemon.conf", "-p", "9999", "-i", "lo" + }; inline static bool ok{false}; }; @@ -259,11 +254,12 @@ struct Client { "map": [ 0, 1 ], )"; - std::string json = json1 + - std::string("\"name\": \"ALSA " + std::to_string(id) + "\",\n") + - std::string("\"source\": \"http://") + - g_daemon_address + ":" + std::to_string(g_daemon_port) + - std::string("/api/source/sdp/") + std::to_string(id) + "\"\n}"; + std::string json = + json1 + + std::string("\"name\": \"ALSA " + std::to_string(id) + "\",\n") + + std::string("\"source\": \"http://") + g_daemon_address + ":" + + std::to_string(g_daemon_port) + std::string("/api/source/sdp/") + + std::to_string(id) + "\"\n}"; std::string url = std::string("/api/sink/") + std::to_string(id); auto res = cli_.Put(url.c_str(), json, "application/json"); BOOST_REQUIRE_MESSAGE(res != nullptr, "server returned response"); @@ -287,9 +283,9 @@ struct Client { auto len = socket_.receive(boost::asio::buffer(data, g_udp_size)); if (len <= g_sap_header_len) { continue; - } - sap_sdp.assign(data + g_sap_header_len, data + len); - } while(data[0] != 0x20 || sap_sdp != sdp); + } + sap_sdp.assign(data + g_sap_header_len, data + len); + } while (data[0] != 0x20 || sap_sdp != sdp); BOOST_CHECK_MESSAGE(true, "SAP announcement SDP and source SDP match"); } return true; @@ -305,10 +301,11 @@ struct Client { } std::string sap_sdp_(data + g_sap_header_len, data + len); if (data[0] == 0x24 && sap_sdp_.length() > 3) { - //o=- 56 0 IN IP4 127.0.0.1 - ids.insert(std::atoi(sap_sdp_.c_str() + 3)); - BOOST_TEST_MESSAGE("waiting deletion for " + - std::to_string(g_stream_num_max - ids.size()) + " sources"); + // o=- 56 0 IN IP4 127.0.0.1 + ids.insert(std::atoi(sap_sdp_.c_str() + 3)); + BOOST_TEST_MESSAGE("waiting deletion for " + + std::to_string(g_stream_num_max - ids.size()) + + " sources"); } } } @@ -322,9 +319,9 @@ struct Client { auto len = socket_.receive(boost::asio::buffer(data, g_udp_size)); if (len <= g_sap_header_len) { continue; - } - sap_sdp.assign(data + g_sap_header_len, data + len); - } while(data[0] != 0x24 || sdp.find(sap_sdp) == std::string::npos); + } + sap_sdp.assign(data + g_sap_header_len, data + len); + } while (data[0] != 0x24 || sdp.find(sap_sdp) == std::string::npos); BOOST_CHECK_MESSAGE(true, "SAP deletion SDP matches"); } return true; @@ -353,7 +350,7 @@ struct Client { BOOST_REQUIRE_MESSAGE(json.first, "got remote mdns sources"); std::stringstream ss(json.second); boost::property_tree::read_json(ss, pt); - //BOOST_TEST_MESSAGE(std::to_string(pt.get_child("remote_sources").size())); + // BOOST_TEST_MESSAGE(std::to_string(pt.get_child("remote_sources").size())); } while (pt.get_child("remote_sources").size() != num && retry--); return (retry > 0); } @@ -379,7 +376,7 @@ BOOST_AUTO_TEST_CASE(get_config) { std::stringstream ss(json.second); boost::property_tree::read_json(ss, pt); auto http_port = pt.get("http_port"); - //auto log_severity = pt.get("log_severity"); + // auto log_severity = pt.get("log_severity"); auto playout_delay = pt.get("playout_delay"); auto tic_frame_size_at_1fs = pt.get("tic_frame_size_at_1fs"); auto max_tic_frame_size = pt.get("max_tic_frame_size"); @@ -396,7 +393,7 @@ BOOST_AUTO_TEST_CASE(get_config) { auto mac_addr = pt.get("mac_addr"); auto ip_addr = pt.get("ip_addr"); BOOST_CHECK_MESSAGE(http_port == 9999, "config as excepcted"); - //BOOST_CHECK_MESSAGE(log_severity == 5, "config as excepcted"); + // BOOST_CHECK_MESSAGE(log_severity == 5, "config as excepcted"); BOOST_CHECK_MESSAGE(playout_delay == 0, "config as excepcted"); BOOST_CHECK_MESSAGE(tic_frame_size_at_1fs == 192, "config as excepcted"); BOOST_CHECK_MESSAGE(max_tic_frame_size == 1024, "config as excepcted"); @@ -407,7 +404,8 @@ BOOST_AUTO_TEST_CASE(get_config) { BOOST_CHECK_MESSAGE(ptp_dscp == 46, "config as excepcted"); BOOST_CHECK_MESSAGE(sap_interval == 1, "config as excepcted"); BOOST_CHECK_MESSAGE(syslog_proto == "none", "config as excepcted"); - BOOST_CHECK_MESSAGE(syslog_server == "255.255.255.254:1234", "config as excepcted"); + BOOST_CHECK_MESSAGE(syslog_server == "255.255.255.254:1234", + "config as excepcted"); BOOST_CHECK_MESSAGE(status_file == "", "config as excepcted"); BOOST_CHECK_MESSAGE(interface_name == "lo", "config as excepcted"); BOOST_CHECK_MESSAGE(mac_addr == "00:00:00:00:00:00", "config as excepcted"); @@ -423,7 +421,8 @@ BOOST_AUTO_TEST_CASE(get_ptp_status) { boost::property_tree::read_json(ss, pt); auto status = pt.get("status"); auto jitter = pt.get("jitter"); - BOOST_REQUIRE_MESSAGE(status == "unlocked" && jitter == 0, "ptp status as excepcted"); + BOOST_REQUIRE_MESSAGE(status == "unlocked" && jitter == 0, + "ptp status as excepcted"); } BOOST_AUTO_TEST_CASE(get_ptp_config) { @@ -455,7 +454,8 @@ BOOST_AUTO_TEST_CASE(set_ptp_config) { boost::property_tree::read_json(fs, pt); domain = pt.get("ptp_domain"); dscp = pt.get("ptp_dscp"); - BOOST_REQUIRE_MESSAGE(domain == 1 && dscp == 48, "ptp config file as excepcted"); + BOOST_REQUIRE_MESSAGE(domain == 1 && dscp == 48, + "ptp config file as excepcted"); res = cli.set_ptp_config(0, 46); BOOST_REQUIRE_MESSAGE(res, "set default ptp config"); } @@ -463,13 +463,14 @@ BOOST_AUTO_TEST_CASE(set_ptp_config) { BOOST_AUTO_TEST_CASE(add_invalid_source) { Client cli; BOOST_REQUIRE_MESSAGE(!cli.add_source(g_stream_num_max), - "not added source " + std::to_string(g_stream_num_max)); + "not added source " + std::to_string(g_stream_num_max)); BOOST_REQUIRE_MESSAGE(!cli.add_source(-1), "not added source -1"); } BOOST_AUTO_TEST_CASE(remove_invalid_source) { Client cli; - BOOST_REQUIRE_MESSAGE(!cli.remove_source(g_stream_num_max), + BOOST_REQUIRE_MESSAGE( + !cli.remove_source(g_stream_num_max), "not removed source " + std::to_string(g_stream_num_max)); BOOST_REQUIRE_MESSAGE(!cli.remove_source(-1), "not removed source -1"); } @@ -522,8 +523,9 @@ BOOST_AUTO_TEST_CASE(source_check_sap_browser) { std::stringstream ss(json.second); boost::property_tree::read_json(ss, pt); BOOST_FOREACH (auto const& v, pt.get_child("remote_sources")) { - BOOST_REQUIRE_MESSAGE(v.second.get("sdp") == sdp.second, - "returned sap source " + v.second.get("id")); + BOOST_REQUIRE_MESSAGE( + v.second.get("sdp") == sdp.second, + "returned sap source " + v.second.get("id")); } BOOST_REQUIRE_MESSAGE(cli.remove_source(0), "removed source 0"); cli.sap_wait_deletion(0, sdp.second, 3); @@ -531,8 +533,8 @@ BOOST_AUTO_TEST_CASE(source_check_sap_browser) { BOOST_REQUIRE_MESSAGE(json.first, "got remote sap sources"); std::stringstream ss1(json.second); boost::property_tree::read_json(ss1, pt); - BOOST_REQUIRE_MESSAGE(pt.get_child("remote_sources").size() == 0, - "no remote sap sources"); + BOOST_REQUIRE_MESSAGE(pt.get_child("remote_sources").size() == 0, + "no remote sap sources"); } #ifdef _USE_AVAHI_ @@ -541,24 +543,28 @@ BOOST_AUTO_TEST_CASE(source_check_mdns_browser) { BOOST_REQUIRE_MESSAGE(cli.add_source(0), "added source 0"); auto sdp = cli.get_source_sdp(0); BOOST_REQUIRE_MESSAGE(sdp.first, "got source sdp 0"); - BOOST_REQUIRE_MESSAGE(cli.wait_for_remote_mdns_sources(1), "remote mdns source found"); + BOOST_REQUIRE_MESSAGE(cli.wait_for_remote_mdns_sources(1), + "remote mdns source found"); auto json = cli.get_remote_mdns_sources(); BOOST_REQUIRE_MESSAGE(json.first, "got remote mdns sources"); boost::property_tree::ptree pt; std::stringstream ss(json.second); boost::property_tree::read_json(ss, pt); BOOST_FOREACH (auto const& v, pt.get_child("remote_sources")) { - BOOST_REQUIRE_MESSAGE(v.second.get("sdp") == sdp.second, - "returned mdns source " + v.second.get("id")); + BOOST_REQUIRE_MESSAGE( + v.second.get("sdp") == sdp.second, + "returned mdns source " + v.second.get("id")); } BOOST_REQUIRE_MESSAGE(cli.remove_source(0), "removed source 0"); - BOOST_REQUIRE_MESSAGE(cli.wait_for_remote_mdns_sources(0), "no remote mdns sources"); + BOOST_REQUIRE_MESSAGE(cli.wait_for_remote_mdns_sources(0), + "no remote mdns sources"); } BOOST_AUTO_TEST_CASE(source_check_mdns_browser_update) { Client cli; BOOST_REQUIRE_MESSAGE(cli.add_source(0), "added source 0"); - BOOST_REQUIRE_MESSAGE(cli.wait_for_remote_mdns_sources(1), "remote mdns source found"); + BOOST_REQUIRE_MESSAGE(cli.wait_for_remote_mdns_sources(1), + "remote mdns source found"); BOOST_REQUIRE_MESSAGE(cli.update_source(0), "updated source 0"); auto sdp = cli.get_source_sdp(0); BOOST_REQUIRE_MESSAGE(sdp.first, "got source sdp 0"); @@ -571,7 +577,7 @@ BOOST_AUTO_TEST_CASE(source_check_mdns_browser_update) { std::stringstream ss(json.second); boost::property_tree::ptree pt; boost::property_tree::read_json(ss, pt); - //BOOST_TEST_MESSAGE(std::to_string(pt.get_child("remote_sources").size())); + // BOOST_TEST_MESSAGE(std::to_string(pt.get_child("remote_sources").size())); BOOST_FOREACH (auto const& v, pt.get_child("remote_sources")) { if (v.second.get("sdp") == sdp.second) { found = true; @@ -580,7 +586,8 @@ BOOST_AUTO_TEST_CASE(source_check_mdns_browser_update) { } while (retry-- && !found); BOOST_REQUIRE_MESSAGE(retry > 0, "remote mdns source updated"); BOOST_REQUIRE_MESSAGE(cli.remove_source(0), "removed source 0"); - BOOST_REQUIRE_MESSAGE(cli.wait_for_remote_mdns_sources(0), "no remote mdns sources"); + BOOST_REQUIRE_MESSAGE(cli.wait_for_remote_mdns_sources(0), + "no remote mdns sources"); } #endif @@ -592,10 +599,10 @@ BOOST_AUTO_TEST_CASE(sink_check_status) { boost::property_tree::ptree pt; std::stringstream ss(json.second); boost::property_tree::read_json(ss, pt); - //auto is_sink_muted = pt.get("sink_flags.muted"); + // auto is_sink_muted = pt.get("sink_flags.muted"); auto is_sink_some_muted = pt.get("sink_flags.some_muted"); auto is_sink_all_muted = pt.get("sink_flags.all_muted"); - //BOOST_REQUIRE_MESSAGE(is_sink_muted, "sink is muted"); + // BOOST_REQUIRE_MESSAGE(is_sink_muted, "sink is muted"); BOOST_REQUIRE_MESSAGE(!is_sink_all_muted, "all sinks are mutes"); BOOST_REQUIRE_MESSAGE(!is_sink_some_muted, "some sinks are muted"); BOOST_REQUIRE_MESSAGE(cli.remove_sink(0), "removed sink 0"); @@ -614,7 +621,7 @@ BOOST_AUTO_TEST_CASE(add_remove_all_sources) { boost::property_tree::read_json(ss, pt); uint8_t id = 0; BOOST_FOREACH (auto const& v, pt.get_child("sources")) { - BOOST_REQUIRE_MESSAGE(v.second.get("id") == id, + BOOST_REQUIRE_MESSAGE(v.second.get("id") == id, "returned source " + std::to_string(id)); ++id; } @@ -637,7 +644,7 @@ BOOST_AUTO_TEST_CASE(add_remove_all_sinks) { boost::property_tree::read_json(ss, pt); uint8_t id = 0; BOOST_FOREACH (auto const& v, pt.get_child("sinks")) { - BOOST_REQUIRE_MESSAGE(v.second.get("id") == id, + BOOST_REQUIRE_MESSAGE(v.second.get("id") == id, "returned sink " + std::to_string(id)); ++id; } @@ -664,13 +671,13 @@ BOOST_AUTO_TEST_CASE(add_remove_check_all) { boost::property_tree::read_json(ss, pt); uint8_t id = 0; BOOST_FOREACH (auto const& v, pt.get_child("sources")) { - BOOST_REQUIRE_MESSAGE(v.second.get("id") == id, + BOOST_REQUIRE_MESSAGE(v.second.get("id") == id, "returned source " + std::to_string(id)); ++id; } id = 0; BOOST_FOREACH (auto const& v, pt.get_child("sinks")) { - BOOST_REQUIRE_MESSAGE(v.second.get("id") == id, + BOOST_REQUIRE_MESSAGE(v.second.get("id") == id, "returned sink " + std::to_string(id)); ++id; } @@ -709,13 +716,13 @@ BOOST_AUTO_TEST_CASE(add_remove_update_check_all) { boost::property_tree::read_json(ss, pt); uint8_t id = 0; BOOST_FOREACH (auto const& v, pt.get_child("sources")) { - BOOST_REQUIRE_MESSAGE(v.second.get("id") == id, + BOOST_REQUIRE_MESSAGE(v.second.get("id") == id, "returned source " + std::to_string(id)); ++id; } id = 0; BOOST_FOREACH (auto const& v, pt.get_child("sinks")) { - BOOST_REQUIRE_MESSAGE(v.second.get("id") == id, + BOOST_REQUIRE_MESSAGE(v.second.get("id") == id, "returned sink " + std::to_string(id)); ++id; } @@ -737,7 +744,8 @@ BOOST_AUTO_TEST_CASE(add_remove_check_sap_browser_all) { } for (int id = 0; id < g_stream_num_max; id++) { auto sdp = cli.get_source_sdp(id); - BOOST_REQUIRE_MESSAGE(sdp.first, std::string("got source sdp ") + std::to_string(id)); + BOOST_REQUIRE_MESSAGE(sdp.first, + std::string("got source sdp ") + std::to_string(id)); cli.sap_wait_announcement(id, sdp.second); } boost::property_tree::ptree pt; @@ -748,10 +756,13 @@ BOOST_AUTO_TEST_CASE(add_remove_check_sap_browser_all) { BOOST_REQUIRE_MESSAGE(json.first, "got remote sap sources"); std::stringstream ss(json.second); boost::property_tree::read_json(ss, pt); - //BOOST_TEST_MESSAGE(std::to_string(pt.get_child("remote_sources").size())); - } while (pt.get_child("remote_sources").size() != g_stream_num_max && retry--); - BOOST_REQUIRE_MESSAGE(pt.get_child("remote_sources").size() == g_stream_num_max, - "found " + std::to_string(pt.get_child("remote_sources").size()) + " remote sap sources"); + // BOOST_TEST_MESSAGE(std::to_string(pt.get_child("remote_sources").size())); + } while (pt.get_child("remote_sources").size() != g_stream_num_max && + retry--); + BOOST_REQUIRE_MESSAGE( + pt.get_child("remote_sources").size() == g_stream_num_max, + "found " + std::to_string(pt.get_child("remote_sources").size()) + + " remote sap sources"); for (int id = 0; id < g_stream_num_max; id++) { BOOST_REQUIRE_MESSAGE(cli.add_sink_sdp(id), std::string("added sink ") + std::to_string(id)); @@ -762,13 +773,13 @@ BOOST_AUTO_TEST_CASE(add_remove_check_sap_browser_all) { boost::property_tree::read_json(ss1, pt); uint8_t id = 0; BOOST_FOREACH (auto const& v, pt.get_child("sources")) { - BOOST_REQUIRE_MESSAGE(v.second.get("id") == id, + BOOST_REQUIRE_MESSAGE(v.second.get("id") == id, "returned source " + std::to_string(id)); ++id; } id = 0; BOOST_FOREACH (auto const& v, pt.get_child("sinks")) { - BOOST_REQUIRE_MESSAGE(v.second.get("id") == id, + BOOST_REQUIRE_MESSAGE(v.second.get("id") == id, "returned sink " + std::to_string(id)); ++id; } @@ -784,9 +795,10 @@ BOOST_AUTO_TEST_CASE(add_remove_check_sap_browser_all) { BOOST_REQUIRE_MESSAGE(json.first, "got remote sap sources"); std::stringstream ss2(json.second); boost::property_tree::read_json(ss2, pt); - //BOOST_TEST_MESSAGE(std::to_string(pt.get_child("remote_sources").size())); + // BOOST_TEST_MESSAGE(std::to_string(pt.get_child("remote_sources").size())); } while (pt.get_child("remote_sources").size() > 0 && retry--); - BOOST_REQUIRE_MESSAGE(pt.get_child("remote_sources").size() == 0, "no remote sap sources"); + BOOST_REQUIRE_MESSAGE(pt.get_child("remote_sources").size() == 0, + "no remote sap sources"); for (int id = 0; id < g_stream_num_max; id++) { BOOST_REQUIRE_MESSAGE(cli.remove_sink(id), std::string("removed sink ") + std::to_string(id)); @@ -800,8 +812,8 @@ BOOST_AUTO_TEST_CASE(add_remove_check_mdns_browser_all) { BOOST_REQUIRE_MESSAGE(cli.add_source(id), std::string("added source ") + std::to_string(id)); } - BOOST_REQUIRE_MESSAGE(cli.wait_for_remote_mdns_sources(g_stream_num_max), - "remote mdns sources found"); + BOOST_REQUIRE_MESSAGE(cli.wait_for_remote_mdns_sources(g_stream_num_max), + "remote mdns sources found"); for (int id = 0; id < g_stream_num_max; id++) { BOOST_REQUIRE_MESSAGE(cli.add_sink_sdp(id), std::string("added sink ") + std::to_string(id)); @@ -813,13 +825,13 @@ BOOST_AUTO_TEST_CASE(add_remove_check_mdns_browser_all) { boost::property_tree::read_json(ss1, pt); uint8_t id = 0; BOOST_FOREACH (auto const& v, pt.get_child("sources")) { - BOOST_REQUIRE_MESSAGE(v.second.get("id") == id, + BOOST_REQUIRE_MESSAGE(v.second.get("id") == id, "returned source " + std::to_string(id)); ++id; } id = 0; BOOST_FOREACH (auto const& v, pt.get_child("sinks")) { - BOOST_REQUIRE_MESSAGE(v.second.get("id") == id, + BOOST_REQUIRE_MESSAGE(v.second.get("id") == id, "returned sink " + std::to_string(id)); ++id; } @@ -827,7 +839,8 @@ BOOST_AUTO_TEST_CASE(add_remove_check_mdns_browser_all) { BOOST_REQUIRE_MESSAGE(cli.remove_source(id), std::string("removed source ") + std::to_string(id)); } - BOOST_REQUIRE_MESSAGE(cli.wait_for_remote_mdns_sources(0), "no remote mdns sources found"); + BOOST_REQUIRE_MESSAGE(cli.wait_for_remote_mdns_sources(0), + "no remote mdns sources found"); for (int id = 0; id < g_stream_num_max; id++) { BOOST_REQUIRE_MESSAGE(cli.remove_sink(id), std::string("removed sink ") + std::to_string(id)); @@ -872,6 +885,7 @@ BOOST_AUTO_TEST_CASE(add_remove_check_mdns_browser_update_all) { BOOST_REQUIRE_MESSAGE(cli.remove_source(id), std::string("removed source ") + std::to_string(id)); } - BOOST_REQUIRE_MESSAGE(cli.wait_for_remote_mdns_sources(0), "no remote mdns sources found"); + BOOST_REQUIRE_MESSAGE(cli.wait_for_remote_mdns_sources(0), + "no remote mdns sources found"); } #endif diff --git a/daemon/utils.cpp b/daemon/utils.cpp index 5278d2e..66c074b 100644 --- a/daemon/utils.cpp +++ b/daemon/utils.cpp @@ -18,9 +18,11 @@ // // -#include #include "utils.hpp" +#include +#include + uint16_t crc16(const uint8_t* p, size_t len) { uint8_t x; uint16_t crc = 0xFFFF; @@ -78,7 +80,20 @@ std::string get_node_id(uint32_t ip_addr) { std::stringstream ss; ip_addr = htonl(ip_addr); /* we create an host ID based on the current IP */ - ss << "AES67 daemon " << boost::format("%08x") % - ((ip_addr << 16) | (ip_addr >> 16)); + ss << "AES67 daemon " + << boost::format("%08x") % ((ip_addr << 16) | (ip_addr >> 16)); return ss.str(); } + +std::string sdp_get_subject(const std::string& sdp) { + std::stringstream ssstrem(sdp); + std::string line; + while (getline(ssstrem, line, '\n')) { + if (line.substr(0, 2) == "s=") { + auto subject = line.substr(2); + boost::trim(subject); + return subject; + } + } + return ""; +} diff --git a/daemon/utils.hpp b/daemon/utils.hpp index 2e97d59..100ccf6 100644 --- a/daemon/utils.hpp +++ b/daemon/utils.hpp @@ -20,11 +20,11 @@ #ifndef _UTILS_HPP_ #define _UTILS_HPP_ -#include -#include - #include +#include +#include + uint16_t crc16(const uint8_t* p, size_t len); std::tuple