diff --git a/daemon/json.cpp b/daemon/json.cpp old mode 100644 new mode 100755 index 6745bd8..38133b1 --- a/daemon/json.cpp +++ b/daemon/json.cpp @@ -96,7 +96,7 @@ std::string config_to_json(const Config& config) { << ",\n \"mdns_enabled\": " << std::boolalpha << config.get_mdns_enabled() << ",\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()) << "\"" + << ",\n \"node_id\": \"" << escape_json(get_node_id(config.get_ip_addr())) << "\"" << "\n}\n"; return ss.str(); } diff --git a/daemon/mdns_server.hpp b/daemon/mdns_server.hpp old mode 100644 new mode 100755 index a056c60..440acb6 --- a/daemon/mdns_server.hpp +++ b/daemon/mdns_server.hpp @@ -59,7 +59,7 @@ class MDNSServer { std::atomic_bool running_{false}; std::shared_ptr session_manager_; std::shared_ptr config_; - std::string node_id_{get_node_id()}; + std::string node_id_{get_node_id(config_->get_ip_addr())}; #ifdef _USE_AVAHI_ using entry_group_bimap_t = diff --git a/daemon/rtsp_client.cpp b/daemon/rtsp_client.cpp old mode 100644 new mode 100755 index c38d99e..bfb7fdc --- a/daemon/rtsp_client.cpp +++ b/daemon/rtsp_client.cpp @@ -166,13 +166,13 @@ std::pair RtspClient::process( } if (!res.content_type.empty() && - res.content_type.rfind("application/sdp", 0) == std::string::npos) { + res.content_type.rfind("application/sdp", 0) == std::string::npos) { BOOST_LOG_TRIVIAL(error) << "rtsp_client:: unsupported content-type " << res.content_type << " from " << "rtsp://" << address << ":" << port << path; - if (is_describe) { + if (is_describe) { return {false, rtsp_source}; - } + } } else { std::stringstream ss; ss << "rtsp:" << std::hex @@ -183,65 +183,65 @@ std::pair RtspClient::process( rtsp_source.source = "mDNS"; rtsp_source.address = address; rtsp_source.sdp = std::move(res.body); - BOOST_LOG_TRIVIAL(info) << "rtsp_client:: completed " - << "rtsp://" << address << ":" << port << path; + BOOST_LOG_TRIVIAL(info) << "rtsp_client:: completed " + << "rtsp://" << address << ":" << port << path; if (is_announce || is_describe) { if (is_announce && announced_name.empty()) { /* if no name from URL we try from SDP file */ announced_name = sdp_get_subject(rtsp_source.sdp); - } + } callback(announced_name.empty() ? name : announced_name, domain, rtsp_source); } - if (is_announce) { + if (is_announce) { s << "RTSP/1.0 200 OK\r\n"; s << "CSeq: " << res.cseq << "\r\n"; s << "\r\n"; - } else if (!is_describe) { + } else if (!is_describe) { s << "RTSP/1.0 405 Method Not Allowed\r\n"; s << "CSeq: " << res.cseq << "\r\n"; s << "\r\n"; - } + } } if (wait_for_updates) { - g_mutex.lock(); - g_active_clients[{name, domain}] = &s; - g_mutex.unlock(); + g_mutex.lock(); + g_active_clients[{name, domain}] = &s; + g_mutex.unlock(); /* we start waiting for updates */ - do { + do { std::getline(s, request); - } while (request.empty() && !s.error()); - if (s.error()) { + } while (request.empty() && !s.error()); + if (s.error()) { BOOST_LOG_TRIVIAL(info) << "rtsp_client:: end: " << s.error().message(); break; - } - BOOST_LOG_TRIVIAL(info) << "rtsp_client:: received " << request; - boost::trim(request); - is_describe = is_announce = false; - announced_name = ""; - std::vector fields; - split(fields, request, boost::is_any_of(" ")); - if (fields.size() >= 2 && fields[0] == "ANNOUNCE") { - auto const [ok, protocol, host, port, path] = parse_url(fields[1]); - if (ok) { - /* if we find a valid announced source name we use it - * otherwise we try from SDP file or we use the mDNS name */ - if (path.rfind("/by-name/") != std::string::npos) { - announced_name = path.substr(9); - BOOST_LOG_TRIVIAL(debug) << "rtsp_client:: found announced name " - << announced_name; } - } - is_announce = true; - } + BOOST_LOG_TRIVIAL(info) << "rtsp_client:: received " << request; + boost::trim(request); + is_describe = is_announce = false; + announced_name = ""; + std::vector fields; + split(fields, request, boost::is_any_of(" ")); + if (fields.size() >= 2 && fields[0] == "ANNOUNCE") { + auto const res = parse_url(fields[1]); + if (std::get<0>(res)) { + /* if we find a valid announced source name we use it + * otherwise we try from SDP file or we use the mDNS name */ + auto path = std::get<4>(res); + if (path.rfind("/by-name/") != std::string::npos) { + announced_name = path.substr(9); + BOOST_LOG_TRIVIAL(debug) << "rtsp_client:: found announced name " + << announced_name; + } + } + is_announce = true; } - } while (wait_for_updates); - + } + } while (wait_for_updates); } catch (std::exception& e) { BOOST_LOG_TRIVIAL(warning) << "rtsp_client:: error with " diff --git a/daemon/rtsp_server.cpp b/daemon/rtsp_server.cpp old mode 100644 new mode 100755 index 3dbe06b..7ab04ec --- a/daemon/rtsp_server.cpp +++ b/daemon/rtsp_server.cpp @@ -46,9 +46,8 @@ void RtspServer::accept() { unsigned int i = 0; for (; i < sessions_.size(); i++) { if (sessions_[i].use_count() == 0) { - auto session = std::make_shared(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(); @@ -75,7 +74,8 @@ bool RtspSession::announce(uint8_t id, /* if a describe request is currently not beeing process * 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() + " " + 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" @@ -164,15 +164,16 @@ bool RtspSession::process_request() { } void RtspSession::build_response(const std::string& url) { - auto const [ok, protocol, host, port, path] = parse_url(url); - if (!ok) { + auto const res = parse_url(url); + if (!std::get<0>(res)) { BOOST_LOG_TRIVIAL(error) << "rtsp_server:: cannot parse URL " << url << " from " << socket_.remote_endpoint(); send_error(400, "Bad Request"); return; } - - auto base_path = std::string("/by-name/") + get_node_id() + " "; + auto path = std::get<4>(res); + 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 old mode 100644 new mode 100755 index 0d42fd7..8f60890 --- a/daemon/rtsp_server.hpp +++ b/daemon/rtsp_server.hpp @@ -39,9 +39,11 @@ class RtspSession : public std::enable_shared_from_this { constexpr static uint16_t max_length = 4096; // byte constexpr static uint16_t session_tout_secs = 10; // sec - RtspSession(std::shared_ptr session_manager, + RtspSession(std::shared_ptr config, + std::shared_ptr session_manager, tcp::socket socket) - : session_manager_(session_manager), + : config_(config), + session_manager_(session_manager), socket_(std::move(socket)), length_{0}, cseq_{-1}, @@ -66,6 +68,7 @@ class RtspSession : public std::enable_shared_from_this { void read_request(); void send_error(int status_code, const std::string& description); void send_response(const std::string& response); + std::shared_ptr config_; std::shared_ptr session_manager_; tcp::socket socket_; char data_[max_length + 1]; diff --git a/daemon/session_manager.cpp b/daemon/session_manager.cpp old mode 100644 new mode 100755 index e86a6a0..6e5ed00 --- a/daemon/session_manager.cpp +++ b/daemon/session_manager.cpp @@ -557,7 +557,8 @@ std::string SessionManager::get_source_sdp_(uint32_t id, ss << "v=0\n" << "o=- " << static_cast(id) << " 0 IN IP4 " << ip::address_v4(info.stream.m_ui32SrcIP).to_string() << "\n" - << "s=" << get_node_id() << " " << info.stream.m_cName << "\n" + << "s=" << get_node_id(config_->get_ip_addr()) << " " + << info.stream.m_cName << "\n" << "c=IN IP4 " << ip::address_v4(info.stream.m_ui32DestIP).to_string() << "/" << static_cast(info.stream.m_byTTL) << "\n" << "t=0 0\n" diff --git a/daemon/utils.cpp b/daemon/utils.cpp old mode 100644 new mode 100755 index 2ff1e79..a89c957 --- a/daemon/utils.cpp +++ b/daemon/utils.cpp @@ -18,6 +18,7 @@ // // +#include #include "utils.hpp" uint16_t crc16(const uint8_t* p, size_t len) { @@ -73,8 +74,19 @@ parse_url(const std::string& _url) { return {host.length() > 0, protocol, host, port, path}; } -std::string get_node_id() { +std::string get_node_id(uint32_t ip_addr) { std::stringstream ss; - ss << "AES67 daemon " << std::hex << (uint32_t)gethostid(); + if (gethostid() == 0x7f0101) { + /* hostid is using lo interface ip + we create an host ID based on the current IP */ + ss << "AES67 daemon " + << boost::format("%02x%02x%02x%02x") + % ((ip_addr >> 8) & 0xff) + % ((ip_addr >> 24) & 0xff) + % (ip_addr & 0xff) + % ((ip_addr >> 16) & 0xff); + } else { + ss << "AES67 daemon " << std::hex << (uint32_t)gethostid(); + } return ss.str(); } diff --git a/daemon/utils.hpp b/daemon/utils.hpp old mode 100644 new mode 100755 index 2f62f64..2e97d59 --- a/daemon/utils.hpp +++ b/daemon/utils.hpp @@ -34,6 +34,6 @@ std::tuple parse_url(const std::string& _url); -std::string get_node_id(); +std::string get_node_id(uint32_t ip_addr); #endif