Applied Clang source code formatting to daemon sources

This commit is contained in:
Andrea Bondavalli 2020-06-16 21:14:44 +02:00
parent f9a07569f9
commit 098cebd056
37 changed files with 674 additions and 681 deletions

View File

@ -129,7 +129,7 @@ RawStringFormats:
CanonicalDelimiter: '' CanonicalDelimiter: ''
BasedOnStyle: google BasedOnStyle: google
ReflowComments: true ReflowComments: true
SortIncludes: true SortIncludes: false
SortUsingDeclarations: true SortUsingDeclarations: true
SpaceAfterCStyleCast: false SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false SpaceAfterLogicalNot: false

View File

@ -26,15 +26,13 @@ using namespace boost::algorithm;
using namespace std::chrono; using namespace std::chrono;
using second_t = duration<double, std::ratio<1> >; using second_t = duration<double, std::ratio<1> >;
std::shared_ptr<Browser> Browser::create( std::shared_ptr<Browser> Browser::create(std::shared_ptr<Config> config) {
std::shared_ptr<Config> config) {
// no need to be thread-safe here // no need to be thread-safe here
static std::weak_ptr<Browser> instance; static std::weak_ptr<Browser> instance;
if (auto ptr = instance.lock()) { if (auto ptr = instance.lock()) {
return ptr; return ptr;
} }
auto ptr = auto ptr = std::shared_ptr<Browser>(new Browser(config));
std::shared_ptr<Browser>(new Browser(config));
instance = ptr; instance = ptr;
return ptr; return ptr;
} }
@ -53,19 +51,6 @@ std::list<RemoteSource> Browser::get_remote_sources(
return sources_list; 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() { bool Browser::worker() {
sap_.set_multicast_interface(config_->get_ip_addr_str()); sap_.set_multicast_interface(config_->get_ip_addr_str());
// Join SAP muticast address // Join SAP muticast address
@ -94,11 +79,16 @@ bool Browser::worker() {
// Source is not in the map // Source is not in the map
if (is_announce) { if (is_announce) {
// annoucement, add new source // annoucement, add new source
sources_.insert({ sources_.insert(
id, "SAP", ip::address_v4(ntohl(addr)).to_string(), {id,
sdp_get_subject(sdp), {}, sdp, "SAP",
static_cast<uint32_t>(duration_cast<second_t>(steady_clock::now() ip::address_v4(ntohl(addr)).to_string(),
- startup_).count()), sdp_get_subject(sdp),
{},
sdp,
static_cast<uint32_t>(
duration_cast<second_t>(steady_clock::now() - startup_)
.count()),
360}); 360});
} }
} else { } else {
@ -114,8 +104,7 @@ bool Browser::worker() {
upd_source.last_seen = last_seen; upd_source.last_seen = last_seen;
sources_.replace(it, upd_source); sources_.replace(it, upd_source);
} else { } else {
BOOST_LOG_TRIVIAL(info) BOOST_LOG_TRIVIAL(info) << "browser:: removing SAP source " << it->id
<< "browser:: removing SAP source " << it->id
<< " name " << it->name; << " name " << it->name;
// deletion, remove entry // deletion, remove entry
sources_.erase(it); sources_.erase(it);
@ -124,11 +113,12 @@ bool Browser::worker() {
} }
// check if it's time to update the SAP remote sources // check if it's time to update the SAP remote sources
if ((duration_cast<second_t>(steady_clock::now() - sap_timepoint).count()) if ((duration_cast<second_t>(steady_clock::now() - sap_timepoint).count()) >
> sap_interval) { sap_interval) {
sap_timepoint = steady_clock::now(); sap_timepoint = steady_clock::now();
// remove all sessions no longer announced // remove all sessions no longer announced
auto offset = duration_cast<second_t>(steady_clock::now() - startup_).count(); auto offset =
duration_cast<second_t>(steady_clock::now() - startup_).count();
std::unique_lock sources_lock(sources_mutex_); std::unique_lock sources_lock(sources_mutex_);
for (auto it = sources_.begin(); it != sources_.end();) { for (auto it = sources_.begin(); it != sources_.end();) {
@ -145,8 +135,8 @@ bool Browser::worker() {
} }
// check if it's time to process the mDNS RTSP sources // check if it's time to process the mDNS RTSP sources
if ((duration_cast<second_t>(steady_clock::now() - mdns_timepoint).count()) if ((duration_cast<second_t>(steady_clock::now() - mdns_timepoint)
> mdns_interval) { .count()) > mdns_interval) {
mdns_timepoint = steady_clock::now(); mdns_timepoint = steady_clock::now();
process_results(); process_results();
} }
@ -158,8 +148,8 @@ bool Browser::worker() {
void Browser::on_change_rtsp_source(const std::string& name, void Browser::on_change_rtsp_source(const std::string& name,
const std::string& domain, const std::string& domain,
const RtspSource& s) { const RtspSource& s) {
uint32_t last_seen = duration_cast<second_t>(steady_clock::now() - uint32_t last_seen =
startup_).count(); duration_cast<second_t>(steady_clock::now() - startup_).count();
std::unique_lock sources_lock(sources_mutex_); std::unique_lock sources_lock(sources_mutex_);
/* search by name */ /* search by name */
auto rng = sources_.get<name_tag>().equal_range(name); auto rng = sources_.get<name_tag>().equal_range(name);
@ -168,8 +158,7 @@ void Browser::on_change_rtsp_source(const std::string& name,
if (it->source == "mDNS" && it->domain == domain) { if (it->source == "mDNS" && it->domain == domain) {
/* mDNS source with same name and domain -> update */ /* mDNS source with same name and domain -> update */
BOOST_LOG_TRIVIAL(info) << "browser:: updating RTSP source " << s.id BOOST_LOG_TRIVIAL(info) << "browser:: updating RTSP source " << s.id
<< " name " << name << " name " << name << " domain " << domain;
<< " domain " << domain;
auto upd_source{*it}; auto upd_source{*it};
upd_source.id = s.id; upd_source.id = s.id;
upd_source.sdp = s.sdp; upd_source.sdp = s.sdp;
@ -181,9 +170,8 @@ void Browser::on_change_rtsp_source(const std::string& name,
++rng.first; ++rng.first;
} }
/* entry not found -> add */ /* entry not found -> add */
BOOST_LOG_TRIVIAL(info) << "browser:: adding RTSP source " << s.id BOOST_LOG_TRIVIAL(info) << "browser:: adding RTSP source " << s.id << " name "
<< " name " << name << name << " domain " << domain;
<< " domain " << domain;
sources_.insert( sources_.insert(
{s.id, s.source, s.address, name, domain, s.sdp, last_seen, 0}); {s.id, s.source, s.address, name, domain, s.sdp, last_seen, 0});
} }
@ -196,8 +184,8 @@ void Browser::on_remove_rtsp_source(const std::string& name,
while (rng.first != rng.second) { while (rng.first != rng.second) {
const auto& it = rng.first; const auto& it = rng.first;
if (it->source == "mDNS" && it->domain == domain) { if (it->source == "mDNS" && it->domain == domain) {
BOOST_LOG_TRIVIAL(info) << "browser:: removing RTSP source " << it->id BOOST_LOG_TRIVIAL(info)
<< " name " << it->name << "browser:: removing RTSP source " << it->id << " name " << it->name
<< " domain " << it->domain; << " domain " << it->domain;
name_idx.erase(it); name_idx.erase(it);
break; break;
@ -230,4 +218,3 @@ bool Browser::terminate() {
} }
return true; return true;
} }

View File

@ -20,22 +20,21 @@
#ifndef _BROWSER_HPP_ #ifndef _BROWSER_HPP_
#define _BROWSER_HPP_ #define _BROWSER_HPP_
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/indexed_by.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index_container.hpp>
#include <chrono>
#include <future> #include <future>
#include <list>
#include <shared_mutex> #include <shared_mutex>
#include <thread> #include <thread>
#include <chrono>
#include <list>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/indexed_by.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/member.hpp>
#include "config.hpp" #include "config.hpp"
#include "sap.hpp"
#include "igmp.hpp" #include "igmp.hpp"
#include "mdns_client.hpp" #include "mdns_client.hpp"
#include "sap.hpp"
using namespace boost::multi_index; using namespace boost::multi_index;
@ -52,8 +51,7 @@ struct RemoteSource {
class Browser : public MDNSClient { class Browser : public MDNSClient {
public: public:
static std::shared_ptr<Browser> create( static std::shared_ptr<Browser> create(std::shared_ptr<Config> config);
std::shared_ptr<Config> config);
Browser() = delete; Browser() = delete;
Browser(const Browser&) = delete; Browser(const Browser&) = delete;
Browser& operator=(const Browser&) = delete; Browser& operator=(const Browser&) = delete;
@ -67,18 +65,15 @@ class Browser : public MDNSClient {
protected: protected:
// singleton, use create() to build // singleton, use create() to build
Browser(std::shared_ptr<Config> config): Browser(std::shared_ptr<Config> config)
MDNSClient(config), : MDNSClient(config), startup_(std::chrono::steady_clock::now()){};
startup_(std::chrono::steady_clock::now()){};
bool worker(); bool worker();
virtual void on_change_rtsp_source( virtual void on_change_rtsp_source(const std::string& name,
const std::string& name,
const std::string& domain, const std::string& domain,
const RtspSource& source) override; const RtspSource& source) override;
virtual void on_remove_rtsp_source( virtual void on_remove_rtsp_source(const std::string& name,
const std::string& name,
const std::string& domain) override; const std::string& domain) override;
std::future<bool> res_; std::future<bool> res_;
@ -86,13 +81,15 @@ class Browser : public MDNSClient {
/* current sources */ /* current sources */
struct id_tag {}; struct id_tag {};
using by_id = hashed_unique<tag<id_tag>, member<RemoteSource, using by_id =
std::string, &RemoteSource::id>>; hashed_unique<tag<id_tag>,
member<RemoteSource, std::string, &RemoteSource::id>>;
struct name_tag {}; struct name_tag {};
using by_name = ordered_non_unique<tag<name_tag>, member<RemoteSource, using by_name = ordered_non_unique<
std::string, &RemoteSource::name>>; tag<name_tag>,
using sources_t = multi_index_container<RemoteSource, member<RemoteSource, std::string, &RemoteSource::name>>;
indexed_by<by_id, by_name>>; using sources_t =
multi_index_container<RemoteSource, indexed_by<by_id, by_name>>;
sources_t sources_; sources_t sources_;
mutable std::shared_mutex sources_mutex_; mutable std::shared_mutex sources_mutex_;

View File

@ -17,23 +17,22 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
// //
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <boost/asio.hpp> #include <boost/asio.hpp>
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <boost/property_tree/json_parser.hpp> #include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/ptree.hpp> #include <boost/property_tree/ptree.hpp>
#include <exception> #include <exception>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include "config.hpp"
#include "interface.hpp" #include "interface.hpp"
#include "json.hpp" #include "json.hpp"
#include "config.hpp"
using namespace boost::asio; using namespace boost::asio;
@ -58,8 +57,7 @@ std::shared_ptr<Config> Config::parse(const std::string& filename) {
config.log_severity_ = 2; config.log_severity_ = 2;
if (config.playout_delay_ > 4000) if (config.playout_delay_ > 4000)
config.playout_delay_ = 4000; config.playout_delay_ = 4000;
if (config.tic_frame_size_at_1fs_ == 0 || if (config.tic_frame_size_at_1fs_ == 0 || config.tic_frame_size_at_1fs_ > 192)
config.tic_frame_size_at_1fs_ > 192)
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_ || if (config.max_tic_frame_size_ < config.tic_frame_size_at_1fs_ ||
config.max_tic_frame_size_ > 1024) config.max_tic_frame_size_ > 1024)

View File

@ -63,7 +63,9 @@ class Config {
void set_http_port(uint16_t http_port) { http_port_ = http_port; }; 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_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_log_severity(int log_severity) { log_severity_ = log_severity; };
void set_playout_delay(uint32_t playout_delay) { void set_playout_delay(uint32_t playout_delay) {
playout_delay_ = playout_delay; playout_delay_ = playout_delay;
@ -105,9 +107,7 @@ class Config {
void set_mac_addr(const std::array<uint8_t, 6>& mac_addr) { void set_mac_addr(const std::array<uint8_t, 6>& mac_addr) {
mac_addr_ = mac_addr; mac_addr_ = mac_addr;
}; };
void set_mdns_enabled(bool enabled) { void set_mdns_enabled(bool enabled) { mdns_enabled_ = enabled; };
mdns_enabled_ = enabled;
};
void set_interface_idx(int index) { interface_idx_ = index; }; void set_interface_idx(int index) { interface_idx_ = index; };
private: private:

View File

@ -20,8 +20,8 @@
#include <iostream> #include <iostream>
#include <thread> #include <thread>
#include "driver_handler.hpp"
#include "log.hpp" #include "log.hpp"
#include "driver_handler.hpp"
/* /*
void dump(const void* mem, unsigned int n) { void dump(const void* mem, unsigned int n) {
@ -183,7 +183,8 @@ void DriverHandler::send_command(enum MT_ALSA_msg_id id,
<< palsa_msg->errCode << " data len " << palsa_msg->dataSize; << palsa_msg->errCode << " data len " << palsa_msg->dataSize;
if (id != palsa_msg->id) { if (id != palsa_msg->id) {
BOOST_LOG_TRIVIAL(warning) << "driver_handler:: unexpected cmd response:" BOOST_LOG_TRIVIAL(warning)
<< "driver_handler:: unexpected cmd response:"
<< "sent " << id << " received " << palsa_msg->id; << "sent " << id << " received " << palsa_msg->id;
on_command_error(palsa_msg->id, DaemonErrc::invalid_driver_response); on_command_error(palsa_msg->id, DaemonErrc::invalid_driver_response);
} else { } else {

View File

@ -24,9 +24,9 @@
#include "MT_ALSA_message_defs.h" #include "MT_ALSA_message_defs.h"
#include "config.hpp" #include "config.hpp"
#include "error_code.hpp"
#include "log.hpp" #include "log.hpp"
#include "netlink_client.hpp" #include "netlink_client.hpp"
#include "error_code.hpp"
class DriverHandler { class DriverHandler {
public: public:

View File

@ -19,11 +19,10 @@
#include <thread> #include <thread>
#include "driver_manager.hpp"
#include "log.hpp" #include "log.hpp"
#include "driver_manager.hpp"
static const std::vector<std::string> alsa_msg_str = { static const std::vector<std::string> alsa_msg_str = {"Start",
"Start",
"Stop", "Stop",
"Reset", "Reset",
"StartIO", "StartIO",
@ -55,14 +54,10 @@ static const std::vector<std::string> alsa_msg_str = {
"GetRTPStreamStatus", "GetRTPStreamStatus",
"SetPTPConfig", "SetPTPConfig",
"GetPTPConfig", "GetPTPConfig",
"GetPTPStatus" "GetPTPStatus"};
};
static const std::vector<std::string> ptp_status_str = { static const std::vector<std::string> ptp_status_str = {"unlocked", "locking",
"unlocked", "locked"};
"locking",
"locked"
};
std::shared_ptr<DriverManager> DriverManager::create() { std::shared_ptr<DriverManager> DriverManager::create() {
// no need to be thread-safe here // 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.ui8Domain = config.get_ptp_domain();
ptp_config.ui8DSCP = config.get_ptp_dscp(); ptp_config.ui8DSCP = config.get_ptp_dscp();
bool res = hello() || bool res = hello() || start() || reset() ||
start() ||
reset() ||
set_interface_name(config.get_interface_name()) || set_interface_name(config.get_interface_name()) ||
set_ptp_config(ptp_config) || set_ptp_config(ptp_config) ||
set_tic_frame_size_at_1fs(config.get_tic_frame_size_at_1fs()) || 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)) { if (req_size == sizeof(int32_t)) {
memcpy(&output_volume, req, req_size); memcpy(&output_volume, req, req_size);
BOOST_LOG_TRIVIAL(info) BOOST_LOG_TRIVIAL(info)
<< "driver_manager:: event SetMasterOutputVolume " << "driver_manager:: event SetMasterOutputVolume " << output_volume;
<< output_volume;
} }
resp_size = 0; resp_size = 0;
break; break;
@ -297,15 +289,15 @@ void DriverManager::on_event(enum MT_ALSA_msg_id id,
if (req_size == sizeof(int32_t)) { if (req_size == sizeof(int32_t)) {
memcpy(&output_switch, req, req_size); memcpy(&output_switch, req, req_size);
BOOST_LOG_TRIVIAL(info) BOOST_LOG_TRIVIAL(info)
<< "driver_manager:: event SetMasterOutputSwitch " << "driver_manager:: event SetMasterOutputSwitch " << output_switch;
<< output_switch;
} }
resp_size = 0; resp_size = 0;
break; break;
case MT_ALSA_Msg_SetSampleRate: case MT_ALSA_Msg_SetSampleRate:
if (req_size == sizeof(uint32_t)) { if (req_size == sizeof(uint32_t)) {
memcpy(&sample_rate, req, req_size); 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; resp_size = 0;
break; break;

View File

@ -23,10 +23,9 @@
#include <boost/asio.hpp> #include <boost/asio.hpp>
#include <mutex> #include <mutex>
#include "driver_handler.hpp"
#include "RTP_stream_info.h" #include "RTP_stream_info.h"
#include "audio_streamer_clock_PTP_defs.h" #include "audio_streamer_clock_PTP_defs.h"
#include "driver_handler.hpp"
class DriverManager : public DriverHandler { class DriverManager : public DriverHandler {
public: public:

View File

@ -23,14 +23,16 @@
#include <iostream> #include <iostream>
#include <string> #include <string>
#include "http_server.hpp"
#include "log.hpp"
#include "json.hpp" #include "json.hpp"
#include "log.hpp"
#include "http_server.hpp"
using namespace httplib; using namespace httplib;
static inline void set_headers(Response& res, const std::string content_type = "") { static inline void set_headers(Response& res,
res.set_header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); 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-Origin", "*");
res.set_header("Access-Control-Allow-Headers", "x-user-id"); res.set_header("Access-Control-Allow-Headers", "x-user-id");
if (!content_type.empty()) { if (!content_type.empty()) {
@ -52,15 +54,14 @@ static inline int get_http_error_status(const std::error_code& code) {
return 500; return 500;
} }
static inline std::string get_http_error_message( static inline std::string get_http_error_message(const std::error_code& code) {
const std::error_code& code) { std::stringstream ss;
std::stringstream ss;; ;
ss << "(" << code.category().name() << ") " << code.message(); ss << "(" << code.category().name() << ") " << code.message();
return ss.str(); return ss.str();
} }
static inline void set_error( static inline void set_error(const std::error_code& code,
const std::error_code& code,
const std::string& message, const std::string& message,
Response& res) { Response& res) {
res.status = get_http_error_status(code); res.status = get_http_error_status(code);
@ -68,8 +69,7 @@ static inline void set_error(
res.body = message + " : " + get_http_error_message(code); res.body = message + " : " + get_http_error_message(code);
} }
static inline void set_error( static inline void set_error(int status,
int status,
const std::string& message, const std::string& message,
Response& res) { Response& res) {
res.status = status; res.status = status;
@ -85,7 +85,8 @@ bool HttpServer::init() {
svr_.set_base_dir(config_->get_http_base_dir().c_str()); svr_.set_base_dir(config_->get_http_base_dir().c_str());
svr_.Get("(/|/Config|/PTP|/Sources|/Sinks|/Browser)", [&](const Request& req, Response& res) { svr_.Get("(/|/Config|/PTP|/Sources|/Sinks|/Browser)",
[&](const Request& req, Response& res) {
std::ifstream file(config_->get_http_base_dir() + "/index.html"); std::ifstream file(config_->get_http_base_dir() + "/index.html");
std::stringstream buffer; std::stringstream buffer;
buffer << file.rdbuf(); buffer << file.rdbuf();
@ -178,7 +179,8 @@ bool HttpServer::init() {
}); });
/* get a source SDP */ /* get a source SDP */
svr_.Get("/api/source/sdp/([0-9]+)", [this](const Request& req, Response& res) { svr_.Get(
"/api/source/sdp/([0-9]+)", [this](const Request& req, Response& res) {
uint32_t id; uint32_t id;
try { try {
id = std::stoi(req.matches[1]); id = std::stoi(req.matches[1]);
@ -196,8 +198,8 @@ bool HttpServer::init() {
}); });
/* get stream status */ /* get stream status */
svr_.Get("/api/sink/status/([0-9]+)", [this](const Request& req, svr_.Get(
Response& res) { "/api/sink/status/([0-9]+)", [this](const Request& req, Response& res) {
uint32_t id; uint32_t id;
try { try {
id = std::stoi(req.matches[1]); id = std::stoi(req.matches[1]);
@ -208,8 +210,8 @@ bool HttpServer::init() {
SinkStreamStatus status; SinkStreamStatus status;
auto ret = session_manager_->get_sink_status(id, status); auto ret = session_manager_->get_sink_status(id, status);
if (ret) { if (ret) {
set_error(ret, "failed to get sink " + std::to_string(id) + set_error(ret, "failed to get sink " + std::to_string(id) + " status",
" status", res); res);
} else { } else {
set_headers(res, "application/json"); set_headers(res, "application/json");
res.body = sink_status_to_json(status); res.body = sink_status_to_json(status);
@ -222,7 +224,8 @@ bool HttpServer::init() {
StreamSource source = json_to_source(req.matches[1], req.body); StreamSource source = json_to_source(req.matches[1], req.body);
auto ret = session_manager_->add_source(source); auto ret = session_manager_->add_source(source);
if (ret) { 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 { } else {
set_headers(res); set_headers(res);
} }
@ -232,7 +235,8 @@ bool HttpServer::init() {
}); });
/* remove a source */ /* remove a source */
svr_.Delete("/api/source/([0-9]+)", [this](const Request& req, Response& res) { svr_.Delete(
"/api/source/([0-9]+)", [this](const Request& req, Response& res) {
uint32_t id; uint32_t id;
try { try {
id = std::stoi(req.matches[1]); id = std::stoi(req.matches[1]);
@ -314,7 +318,8 @@ bool HttpServer::init() {
}); });
/* wait for HTTP server to show up */ /* 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; int retry = 3;
while (retry--) { while (retry--) {
auto res = cli.Get("/api/config"); auto res = cli.Get("/api/config");

View File

@ -22,9 +22,9 @@
#include <httplib.h> #include <httplib.h>
#include "browser.hpp"
#include "config.hpp" #include "config.hpp"
#include "session_manager.hpp" #include "session_manager.hpp"
#include "browser.hpp"
class HttpServer { class HttpServer {
public: public:
@ -32,9 +32,7 @@ class HttpServer {
HttpServer(std::shared_ptr<SessionManager> session_manager, HttpServer(std::shared_ptr<SessionManager> session_manager,
std::shared_ptr<Browser> browser, std::shared_ptr<Browser> browser,
std::shared_ptr<Config> config) std::shared_ptr<Config> config)
: session_manager_(session_manager), : session_manager_(session_manager), browser_(browser), config_(config){};
browser_(browser),
config_(config) {};
bool init(); bool init();
bool terminate(); bool terminate();

View File

@ -21,8 +21,9 @@
#define _IGMP_HPP_ #define _IGMP_HPP_
#include <boost/asio.hpp> #include <boost/asio.hpp>
#include <mutex>
#include <map> #include <map>
#include <mutex>
#include "log.hpp" #include "log.hpp"
using namespace boost::asio; using namespace boost::asio;
@ -38,7 +39,8 @@ class IGMP {
}; };
bool join(const std::string& interface_ip, const std::string& mcast_ip) { 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<std::mutex> lock(mutex); std::lock_guard<std::mutex> lock(mutex);
auto it = mcast_ref.find(mcast_ip_addr); auto it = mcast_ref.find(mcast_ip_addr);
@ -61,18 +63,19 @@ class IGMP {
ip::multicast::enable_loopback el_option(true); ip::multicast::enable_loopback el_option(true);
socket_.set_option(el_option, ec); socket_.set_option(el_option, ec);
if (ec) { if (ec) {
BOOST_LOG_TRIVIAL(error) << "igmp:: enable loopback option " BOOST_LOG_TRIVIAL(error)
<< ec.message(); << "igmp:: enable loopback option " << ec.message();
} }
BOOST_LOG_TRIVIAL(info) << "igmp:: joined multicast group " BOOST_LOG_TRIVIAL(info) << "igmp:: joined multicast group " << mcast_ip
<< mcast_ip << " on " << interface_ip; << " on " << interface_ip;
mcast_ref[mcast_ip_addr] = 1; mcast_ref[mcast_ip_addr] = 1;
return true; return true;
} }
bool leave(const std::string& interface_ip, const std::string& mcast_ip) { 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<std::mutex> lock(mutex); std::lock_guard<std::mutex> lock(mutex);
auto it = mcast_ref.find(mcast_ip_addr); auto it = mcast_ref.find(mcast_ip_addr);
@ -95,8 +98,8 @@ class IGMP {
return false; return false;
} }
BOOST_LOG_TRIVIAL(info) << "igmp:: left multicast group " BOOST_LOG_TRIVIAL(info)
<< mcast_ip << " on " << interface_ip; << "igmp:: left multicast group " << mcast_ip << " on " << interface_ip;
return true; return true;
} }

View File

@ -18,8 +18,9 @@
// MIT License // MIT License
// //
#include <utility>
#include <boost/asio.hpp> #include <boost/asio.hpp>
#include <utility>
#include "log.hpp" #include "log.hpp"
using namespace boost::asio; using namespace boost::asio;
@ -79,8 +80,8 @@ std::pair<std::array<uint8_t, 6>, std::string> get_interface_mac(
std::copy(sa, sa + 8, std::begin(mac)); std::copy(sa, sa + 8, std::begin(mac));
char str_mac[18]; char str_mac[18];
sprintf(str_mac, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", sprintf(str_mac, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", mac[0], mac[1], mac[2],
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); mac[3], mac[4], mac[5]);
/*BOOST_LOG_TRIVIAL(debug) << "interface " << interface_name /*BOOST_LOG_TRIVIAL(debug) << "interface " << interface_name
<< " MAC address " << str_mac;*/ << " MAC address " << str_mac;*/

View File

@ -20,14 +20,13 @@
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <boost/property_tree/json_parser.hpp> #include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/ptree.hpp> #include <boost/property_tree/ptree.hpp>
#include <regex>
#include <iostream> #include <iostream>
#include <regex>
#include <string> #include <string>
#include "json.hpp"
#include "log.hpp" #include "log.hpp"
#include "utils.hpp" #include "utils.hpp"
#include "json.hpp"
static inline std::string remove_undesired_chars(const std::string& s) { static inline std::string remove_undesired_chars(const std::string& s) {
std::regex html_regex("[^ A-Za-z0-9:~._/=%\()\\r\\n\\t\?#-]?"); 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 \"tic_frame_size_at_1fs\": " << config.get_tic_frame_size_at_1fs()
<< ",\n \"max_tic_frame_size\": " << config.get_max_tic_frame_size() << ",\n \"max_tic_frame_size\": " << config.get_max_tic_frame_size()
<< ",\n \"sample_rate\": " << config.get_sample_rate() << ",\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 \"rtp_port\": " << config.get_rtp_port()
<< ",\n \"ptp_domain\": " << unsigned(config.get_ptp_domain()) << ",\n \"ptp_domain\": " << unsigned(config.get_ptp_domain())
<< ",\n \"ptp_dscp\": " << unsigned(config.get_ptp_dscp()) << ",\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 \"sap_interval\": " << config.get_sap_interval()
<< ",\n \"syslog_proto\": \"" << escape_json(config.get_syslog_proto()) << "\"" << ",\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 \"syslog_server\": \"" << escape_json(config.get_syslog_server())
<< ",\n \"interface_name\": \"" << escape_json(config.get_interface_name()) << "\"" << "\""
<< ",\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 \"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 \"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"; << "\n}\n";
return ss.str(); return ss.str();
} }
@ -272,11 +279,13 @@ Config json_to_config_(std::istream& js, Config& config) {
} else if (key == "rtsp_port") { } else if (key == "rtsp_port") {
config.set_rtsp_port(val.get_value<int>()); config.set_rtsp_port(val.get_value<int>());
} else if (key == "http_base_dir") { } else if (key == "http_base_dir") {
config.set_http_base_dir(remove_undesired_chars(val.get_value<std::string>())); config.set_http_base_dir(
remove_undesired_chars(val.get_value<std::string>()));
} else if (key == "log_severity") { } else if (key == "log_severity") {
config.set_log_severity(val.get_value<int>()); config.set_log_severity(val.get_value<int>());
} else if (key == "interface_name") { } else if (key == "interface_name") {
config.set_interface_name(remove_undesired_chars(val.get_value<std::string>())); config.set_interface_name(
remove_undesired_chars(val.get_value<std::string>()));
} else if (key == "playout_delay") { } else if (key == "playout_delay") {
config.set_playout_delay(val.get_value<uint32_t>()); config.set_playout_delay(val.get_value<uint32_t>());
} else if (key == "tic_frame_size_at_1fs") { } 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") { } else if (key == "sample_rate") {
config.set_sample_rate(val.get_value<uint32_t>()); config.set_sample_rate(val.get_value<uint32_t>());
} else if (key == "rtp_mcast_base") { } else if (key == "rtp_mcast_base") {
config.set_rtp_mcast_base(remove_undesired_chars(val.get_value<std::string>())); config.set_rtp_mcast_base(
remove_undesired_chars(val.get_value<std::string>()));
} else if (key == "rtp_port") { } else if (key == "rtp_port") {
config.set_rtp_port(val.get_value<uint16_t>()); config.set_rtp_port(val.get_value<uint16_t>());
} else if (key == "ptp_domain") { } else if (key == "ptp_domain") {
@ -294,17 +304,21 @@ Config json_to_config_(std::istream& js, Config& config) {
} else if (key == "ptp_dscp") { } else if (key == "ptp_dscp") {
config.set_ptp_dscp(val.get_value<uint8_t>()); config.set_ptp_dscp(val.get_value<uint8_t>());
} else if (key == "sap_mcast_addr") { } else if (key == "sap_mcast_addr") {
config.set_sap_mcast_addr(remove_undesired_chars(val.get_value<std::string>())); config.set_sap_mcast_addr(
remove_undesired_chars(val.get_value<std::string>()));
} else if (key == "sap_interval") { } else if (key == "sap_interval") {
config.set_sap_interval(val.get_value<uint16_t>()); config.set_sap_interval(val.get_value<uint16_t>());
} else if (key == "mdns_enabled") { } else if (key == "mdns_enabled") {
config.set_mdns_enabled(val.get_value<bool>()); config.set_mdns_enabled(val.get_value<bool>());
} else if (key == "status_file") { } else if (key == "status_file") {
config.set_status_file(remove_undesired_chars(val.get_value<std::string>())); config.set_status_file(
remove_undesired_chars(val.get_value<std::string>()));
} else if (key == "syslog_proto") { } else if (key == "syslog_proto") {
config.set_syslog_proto(remove_undesired_chars(val.get_value<std::string>())); config.set_syslog_proto(
remove_undesired_chars(val.get_value<std::string>()));
} else if (key == "syslog_server") { } else if (key == "syslog_server") {
config.set_syslog_server(remove_undesired_chars(val.get_value<std::string>())); config.set_syslog_server(
remove_undesired_chars(val.get_value<std::string>()));
} else if (key == "mac_addr" || key == "ip_addr" || key == "node_id") { } else if (key == "mac_addr" || key == "ip_addr" || key == "node_id") {
/* ignored */ /* ignored */
} else { } else {
@ -455,7 +469,8 @@ static void parse_json_sources(boost::property_tree::ptree& pt,
source.enabled = v.second.get<bool>("enabled"); source.enabled = v.second.get<bool>("enabled");
source.name = v.second.get<std::string>("name"); source.name = v.second.get<std::string>("name");
source.io = v.second.get<std::string>("io"); source.io = v.second.get<std::string>("io");
source.max_samples_per_packet = v.second.get<uint32_t>("max_samples_per_packet"); source.max_samples_per_packet =
v.second.get<uint32_t>("max_samples_per_packet");
source.codec = v.second.get<std::string>("codec"); source.codec = v.second.get<std::string>("codec");
source.ttl = v.second.get<uint8_t>("ttl"); source.ttl = v.second.get<uint8_t>("ttl");
source.payload_type = v.second.get<uint8_t>("payload_type"); source.payload_type = v.second.get<uint8_t>("payload_type");
@ -471,8 +486,7 @@ static void parse_json_sources(boost::property_tree::ptree& pt,
} }
} }
void json_to_sources(std::istream& js, void json_to_sources(std::istream& js, std::list<StreamSource>& sources) {
std::list<StreamSource>& sources) {
try { try {
boost::property_tree::ptree pt; boost::property_tree::ptree pt;
boost::property_tree::read_json(js, 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, void json_to_sinks(const std::string& json, std::list<StreamSink>& sinks) {
std::list<StreamSink>& sinks) {
std::stringstream ss(json); std::stringstream ss(json);
return json_to_sinks(ss, sinks); 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, void json_to_sinks(std::istream& js, std::list<StreamSink>& sinks) {
std::list<StreamSink>& sinks) {
try { try {
boost::property_tree::ptree pt; boost::property_tree::ptree pt;
boost::property_tree::read_json(js, pt); boost::property_tree::read_json(js, pt);
@ -543,4 +555,3 @@ void json_to_streams(std::istream& js,
std::to_string(je.line()) + " :" + je.message()); std::to_string(je.line()) + " :" + je.message());
} }
} }

View File

@ -21,8 +21,9 @@
#define _JSON_HPP_ #define _JSON_HPP_
#include <list> #include <list>
#include "session_manager.hpp"
#include "browser.hpp" #include "browser.hpp"
#include "session_manager.hpp"
/* JSON serializers */ /* JSON serializers */
std::string config_to_json(const Config& config); 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); StreamSource json_to_source(const std::string& id, const std::string& json);
StreamSink json_to_sink(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); PTPConfig json_to_ptp_config(const std::string& json);
void json_to_sources(std::istream& jstream, void json_to_sources(std::istream& jstream, std::list<StreamSource>& sources);
std::list<StreamSource>& sources); void json_to_sources(const std::string& json, std::list<StreamSource>& sources);
void json_to_sources(const std::string& json, void json_to_sinks(std::istream& jstream, std::list<StreamSink>& sinks);
std::list<StreamSource>& sources); void json_to_sinks(const std::string& json, std::list<StreamSink>& sinks);
void json_to_sinks(std::istream& jstream,
std::list<StreamSink>& sinks);
void json_to_sinks(const std::string& json,
std::list<StreamSink>& sinks);
void json_to_streams(std::istream& jstream, void json_to_streams(std::istream& jstream,
std::list<StreamSource>& sources, std::list<StreamSource>& sources,
std::list<StreamSink>& sinks); std::list<StreamSink>& sinks);

View File

@ -17,14 +17,13 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
// //
#include <vector>
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <boost/log/core.hpp> #include <boost/log/core.hpp>
#include <boost/log/sinks/syslog_backend.hpp> #include <boost/log/sinks/syslog_backend.hpp>
#include <boost/log/sources/severity_logger.hpp> #include <boost/log/sources/severity_logger.hpp>
#include <boost/log/trivial.hpp> #include <boost/log/trivial.hpp>
#include <boost/log/utility/setup/console.hpp> #include <boost/log/utility/setup/console.hpp>
#include <vector>
#include "config.hpp" #include "config.hpp"
#include "log.hpp" #include "log.hpp"
@ -37,7 +36,6 @@ namespace keywords = boost::log::keywords;
using sink_t = sinks::synchronous_sink<sinks::syslog_backend>; using sink_t = sinks::synchronous_sink<sinks::syslog_backend>;
void log_init(const Config& config) { void log_init(const Config& config) {
boost::shared_ptr<logging::core> core = logging::core::get(); boost::shared_ptr<logging::core> core = logging::core::get();
// remove all sink in case of re-configuration // remove all sink in case of re-configuration
@ -84,4 +82,3 @@ void log_init(const Config& config) {
core->add_sink(boost::make_shared<sink_t>(backend)); core->add_sink(boost::make_shared<sink_t>(backend));
} }
} }

View File

@ -21,15 +21,15 @@
#include <iostream> #include <iostream>
#include <thread> #include <thread>
#include "browser.hpp"
#include "config.hpp" #include "config.hpp"
#include "driver_manager.hpp" #include "driver_manager.hpp"
#include "http_server.hpp" #include "http_server.hpp"
#include "interface.hpp"
#include "log.hpp"
#include "mdns_server.hpp" #include "mdns_server.hpp"
#include "rtsp_server.hpp" #include "rtsp_server.hpp"
#include "log.hpp"
#include "session_manager.hpp" #include "session_manager.hpp"
#include "interface.hpp"
#include "browser.hpp"
namespace po = boost::program_options; namespace po = boost::program_options;
namespace postyle = boost::program_options::command_line_style; namespace postyle = boost::program_options::command_line_style;
@ -50,12 +50,12 @@ bool is_terminated() {
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
int rc = EXIT_SUCCESS; int rc = EXIT_SUCCESS;
po::options_description desc("Options"); po::options_description desc("Options");
desc.add_options() desc.add_options()(
("config,c", po::value<std::string>()->default_value("/etc/daemon.conf"), "config,c", po::value<std::string>()->default_value("/etc/daemon.conf"),
"daemon configuration file") "daemon configuration file")("interface_name,i", po::value<std::string>(),
("interface_name,i", po::value<std::string>(), "Network interface name") "Network interface name")(
("http_port,p", po::value<int>(), "HTTP server port") "http_port,p", po::value<int>(), "HTTP server port")(
("help,h", "Print this help message"); "help,h", "Print this help message");
int unix_style = postyle::unix_style | postyle::short_allow_next; int unix_style = postyle::unix_style | postyle::short_allow_next;
po::variables_map vm; po::variables_map vm;
@ -114,8 +114,7 @@ int main(int argc, char* argv[]) {
/* start session manager */ /* start session manager */
auto session_manager = SessionManager::create(driver, config); auto session_manager = SessionManager::create(driver, config);
if (session_manager == nullptr || !session_manager->init()) { if (session_manager == nullptr || !session_manager->init()) {
throw std::runtime_error( throw std::runtime_error(std::string("SessionManager:: init failed"));
std::string("SessionManager:: init failed"));
} }
/* start mDNS server */ /* start mDNS server */
@ -133,8 +132,7 @@ int main(int argc, char* argv[]) {
/* start browser */ /* start browser */
auto browser = Browser::create(config); auto browser = Browser::create(config);
if (browser == nullptr || !browser->init()) { if (browser == nullptr || !browser->init()) {
throw std::runtime_error( throw std::runtime_error(std::string("Browser:: init failed"));
std::string("Browser:: init failed"));
} }
/* start http server */ /* start http server */
@ -150,7 +148,8 @@ int main(int argc, char* argv[]) {
while (!is_terminated()) { while (!is_terminated()) {
auto [ip_addr, ip_str] = get_interface_ip(config->get_interface_name()); auto [ip_addr, ip_str] = get_interface_ip(config->get_interface_name());
if (!ip_str.empty() && config->get_ip_addr_str() != ip_str) { 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_str(ip_str);
config->set_ip_addr(ip_addr); config->set_ip_addr(ip_addr);
break; break;
@ -169,27 +168,23 @@ int main(int argc, char* argv[]) {
/* stop http server */ /* stop http server */
if (!http_server.terminate()) { if (!http_server.terminate()) {
throw std::runtime_error( throw std::runtime_error(std::string("HttpServer:: terminate failed"));
std::string("HttpServer:: terminate failed"));
} }
/* stop browser */ /* stop browser */
if (!browser->terminate()) { if (!browser->terminate()) {
throw std::runtime_error( throw std::runtime_error(std::string("Browser:: terminate failed"));
std::string("Browser:: terminate failed"));
} }
/* stop rtsp server */ /* stop rtsp server */
if (!rtsp_server.terminate()) { if (!rtsp_server.terminate()) {
throw std::runtime_error( throw std::runtime_error(std::string("RtspServer:: terminate failed"));
std::string("RtspServer:: terminate failed"));
} }
/* stop mDNS server */ /* stop mDNS server */
if (config->get_mdns_enabled()) { if (config->get_mdns_enabled()) {
if (!mdns_server.terminate()) { if (!mdns_server.terminate()) {
throw std::runtime_error( throw std::runtime_error(std::string("MDNServer:: terminate failed"));
std::string("MDNServer:: terminate failed"));
} }
} }

View File

@ -17,7 +17,6 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
// //
#ifndef _MAIN_HPP_ #ifndef _MAIN_HPP_
#define _MAIN_HPP_ #define _MAIN_HPP_

View File

@ -25,6 +25,7 @@
#include "rtsp_client.hpp" #include "rtsp_client.hpp"
#include "mdns_client.hpp" #include "mdns_client.hpp"
#ifdef _USE_AVAHI_ #ifdef _USE_AVAHI_
void MDNSClient::resolve_callback(AvahiServiceResolver* r, void MDNSClient::resolve_callback(AvahiServiceResolver* r,
AvahiIfIndex interface, AvahiIfIndex interface,
@ -58,7 +59,8 @@ void MDNSClient::resolve_callback(AvahiServiceResolver* r,
char addr[AVAHI_ADDRESS_STR_MAX]; char addr[AVAHI_ADDRESS_STR_MAX];
if ((flags & AVAHI_LOOKUP_RESULT_LOCAL) && if ((flags & AVAHI_LOOKUP_RESULT_LOCAL) &&
(mdns.config_->get_interface_name() == "lo")) { (mdns.config_->get_interface_name() == "lo")) {
::strncpy(addr, mdns.config_->get_ip_addr_str().c_str(), sizeof addr - 1); ::strncpy(addr, mdns.config_->get_ip_addr_str().c_str(),
sizeof addr - 1);
addr[sizeof addr - 1] = 0; addr[sizeof addr - 1] = 0;
} else { } else {
avahi_address_snprint(addr, sizeof(addr), address); avahi_address_snprint(addr, sizeof(addr), address);
@ -72,16 +74,16 @@ void MDNSClient::resolve_callback(AvahiServiceResolver* r,
"wide_area: %i, " "wide_area: %i, "
"multicast: %i, " "multicast: %i, "
"cached: %i", "cached: %i",
host_name, port, addr, host_name, port, addr, !!(flags & AVAHI_LOOKUP_RESULT_LOCAL),
!!(flags & AVAHI_LOOKUP_RESULT_LOCAL),
!!(flags & AVAHI_LOOKUP_RESULT_OUR_OWN), !!(flags & AVAHI_LOOKUP_RESULT_OUR_OWN),
!!(flags & AVAHI_LOOKUP_RESULT_WIDE_AREA), !!(flags & AVAHI_LOOKUP_RESULT_WIDE_AREA),
!!(flags & AVAHI_LOOKUP_RESULT_MULTICAST), !!(flags & AVAHI_LOOKUP_RESULT_MULTICAST),
!!(flags & AVAHI_LOOKUP_RESULT_CACHED)); !!(flags & AVAHI_LOOKUP_RESULT_CACHED));
BOOST_LOG_TRIVIAL(debug) << "mdns_client:: (Resolver) " << info; BOOST_LOG_TRIVIAL(debug) << "mdns_client:: (Resolver) " << info;
/* if not on loopback interface we don't want to receive self announced sessions /* if not on loopback interface we don't want to receive self announced
* or if on loopback interface we want only local announced sessions */ * sessions or if on loopback interface we want only local announced
* sessions */
if ((!(flags & AVAHI_LOOKUP_RESULT_LOCAL) && if ((!(flags & AVAHI_LOOKUP_RESULT_LOCAL) &&
(mdns.config_->get_interface_name() != "lo")) || (mdns.config_->get_interface_name() != "lo")) ||
((flags & AVAHI_LOOKUP_RESULT_LOCAL) && ((flags & AVAHI_LOOKUP_RESULT_LOCAL) &&
@ -91,8 +93,7 @@ void MDNSClient::resolve_callback(AvahiServiceResolver* r,
/* process RTSP client in async task */ /* process RTSP client in async task */
mdns.sources_res_.emplace_back(std::async( mdns.sources_res_.emplace_back(std::async(
std::launch::async, std::launch::async,
[&mdns, [&mdns, name_ = std::forward<std::string>(name),
name_ = std::forward<std::string>(name),
domain_ = std::forward<std::string>(domain), domain_ = std::forward<std::string>(domain),
addr_ = std::forward<std::string>(addr), addr_ = std::forward<std::string>(addr),
port_ = std::forward<std::string>(std::to_string(port))] { port_ = std::forward<std::string>(std::to_string(port))] {
@ -100,8 +101,8 @@ void MDNSClient::resolve_callback(AvahiServiceResolver* r,
std::bind(&MDNSClient::on_change_rtsp_source, &mdns, std::bind(&MDNSClient::on_change_rtsp_source, &mdns,
std::placeholders::_1, std::placeholders::_2, std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3), std::placeholders::_3),
name_, domain_, std::string("/by-name/") + name_, name_, domain_, std::string("/by-name/") + name_, addr_,
addr_, port_); port_);
})); }));
} }
@ -143,10 +144,9 @@ void MDNSClient::browse_callback(AvahiServiceBrowser* b,
/* if already running we don't run a new resolver */ /* if already running we don't run a new resolver */
BOOST_LOG_TRIVIAL(info) BOOST_LOG_TRIVIAL(info)
<< "mdns_client:: (Browser): resolution already ongoing ..."; << "mdns_client:: (Browser): resolution already ongoing ...";
} } else if (!(avahi_service_resolver_new(
else if (!(avahi_service_resolver_new(mdns.client_.get(), interface, mdns.client_.get(), interface, protocol, name, type,
protocol, name, type, domain, domain, AVAHI_PROTO_UNSPEC, AVAHI_LOOKUP_NO_TXT,
AVAHI_PROTO_UNSPEC, AVAHI_LOOKUP_NO_TXT,
resolve_callback, &mdns))) { resolve_callback, &mdns))) {
BOOST_LOG_TRIVIAL(error) BOOST_LOG_TRIVIAL(error)
<< "mdns_client:: " << "mdns_client:: "
@ -194,11 +194,10 @@ void MDNSClient::client_callback(AvahiClient* client,
case AVAHI_CLIENT_S_RUNNING: case AVAHI_CLIENT_S_RUNNING:
case AVAHI_CLIENT_S_COLLISION: case AVAHI_CLIENT_S_COLLISION:
/* Create the service browser */ /* Create the service browser */
mdns.sb_.reset(avahi_service_browser_new(client, mdns.sb_.reset(avahi_service_browser_new(
mdns.config_->get_interface_idx(), client, mdns.config_->get_interface_idx(), AVAHI_PROTO_INET,
AVAHI_PROTO_INET, "_ravenna_session._sub._rtsp._tcp", nullptr, {}, browse_callback,
"_ravenna_session._sub._rtsp._tcp", &mdns));
nullptr, {}, browse_callback, &mdns));
if (mdns.sb_ == nullptr) { if (mdns.sb_ == nullptr) {
BOOST_LOG_TRIVIAL(fatal) BOOST_LOG_TRIVIAL(fatal)
<< "mdns_client:: failed to create service browser: " << "mdns_client:: failed to create service browser: "
@ -210,7 +209,6 @@ void MDNSClient::client_callback(AvahiClient* client,
case AVAHI_CLIENT_CONNECTING: case AVAHI_CLIENT_CONNECTING:
break; break;
} }
} }
#endif #endif

View File

@ -30,9 +30,9 @@
#include <future> #include <future>
#include <list> #include <list>
#include <set>
#include <shared_mutex> #include <shared_mutex>
#include <thread> #include <thread>
#include <set>
#include "config.hpp" #include "config.hpp"
#include "rtsp_client.hpp" #include "rtsp_client.hpp"
@ -64,10 +64,10 @@ class MDNSClient {
#ifdef _USE_AVAHI_ #ifdef _USE_AVAHI_
/* order is important here */ /* order is important here */
std::unique_ptr<AvahiThreadedPoll, decltype(&avahi_threaded_poll_free)> std::unique_ptr<AvahiThreadedPoll, decltype(&avahi_threaded_poll_free)> poll_{
poll_{nullptr, &avahi_threaded_poll_free}; nullptr, &avahi_threaded_poll_free};
std::unique_ptr<AvahiClient, decltype(&avahi_client_free)> std::unique_ptr<AvahiClient, decltype(&avahi_client_free)> client_{
client_{nullptr, &avahi_client_free}; nullptr, &avahi_client_free};
std::unique_ptr<AvahiServiceBrowser, decltype(&avahi_service_browser_free)> std::unique_ptr<AvahiServiceBrowser, decltype(&avahi_service_browser_free)>
sb_{nullptr, &avahi_service_browser_free}; sb_{nullptr, &avahi_service_browser_free};

View File

@ -19,14 +19,14 @@
#include <boost/asio.hpp> #include <boost/asio.hpp>
#include "mdns_server.hpp"
#include "config.hpp" #include "config.hpp"
#include "interface.hpp" #include "interface.hpp"
#include "log.hpp" #include "log.hpp"
#include "utils.hpp" #include "utils.hpp"
#include "mdns_server.hpp"
#ifdef _USE_AVAHI_ #ifdef _USE_AVAHI_
struct AvahiLockGuard { struct AvahiLockGuard {
AvahiLockGuard() = delete; AvahiLockGuard() = delete;
AvahiLockGuard(AvahiThreadedPoll* poll) : poll_(poll) { AvahiLockGuard(AvahiThreadedPoll* poll) : poll_(poll) {
@ -323,8 +323,8 @@ bool MDNSServer::init() {
session_manager_->add_source_observer( session_manager_->add_source_observer(
SessionManager::ObserverType::add_source, SessionManager::ObserverType::add_source,
std::bind(&MDNSServer::add_service, this, std::bind(&MDNSServer::add_service, this, std::placeholders::_2,
std::placeholders::_2, std::placeholders::_3)); std::placeholders::_3));
session_manager_->add_source_observer( session_manager_->add_source_observer(
SessionManager::ObserverType::remove_source, SessionManager::ObserverType::remove_source,

View File

@ -33,16 +33,15 @@
#include <mutex> #include <mutex>
#include <thread> #include <thread>
#include "session_manager.hpp"
#include "config.hpp" #include "config.hpp"
#include "session_manager.hpp"
#include "utils.hpp" #include "utils.hpp"
class MDNSServer { class MDNSServer {
public: public:
MDNSServer(std::shared_ptr<SessionManager> session_manager, MDNSServer(std::shared_ptr<SessionManager> session_manager,
std::shared_ptr<Config> config) std::shared_ptr<Config> config)
: session_manager_(session_manager), : session_manager_(session_manager), config_(config) {}
config_(config){}
MDNSServer() = delete; MDNSServer() = delete;
MDNSServer(const MDNSServer&) = delete; MDNSServer(const MDNSServer&) = delete;

View File

@ -59,7 +59,8 @@ class nl_endpoint {
std::size_t size() const { return sizeof(sockaddr); } 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); } std::size_t capacity() const { return sizeof(sockaddr); }
}; };
@ -81,7 +82,6 @@ class nl_protocol {
private: private:
int proto; int proto;
}; };
#endif #endif

View File

@ -45,9 +45,7 @@ class NetlinkClient {
check_deadline(); check_deadline();
} }
void terminate() { void terminate() { socket_.close(); }
socket_.close();
}
std::size_t receive(const boost::asio::mutable_buffer& buffer, std::size_t receive(const boost::asio::mutable_buffer& buffer,
boost::posix_time::time_duration timeout, boost::posix_time::time_duration timeout,
@ -79,7 +77,8 @@ class NetlinkClient {
if (deadline_.expires_at() <= deadline_timer::traits_type::now()) { if (deadline_.expires_at() <= deadline_timer::traits_type::now()) {
socket_.cancel(); socket_.cancel();
deadline_.expires_at(boost::posix_time::pos_infin); 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)); deadline_.async_wait(boost::bind(&NetlinkClient::check_deadline, this));

View File

@ -44,19 +44,6 @@ struct RtspResponse {
std::string body; 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 read_response(tcp::iostream& s, uint16_t max_length) {
RtspResponse res; RtspResponse res;
std::string header; std::string header;

View File

@ -15,12 +15,12 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "rtsp_server.hpp"
#include "utils.hpp" #include "utils.hpp"
#include "rtsp_server.hpp"
using boost::asio::ip::tcp; using boost::asio::ip::tcp;
bool RtspServer::update_source(uint8_t id, bool RtspServer::update_source(uint8_t id,
const std::string& name, const std::string& name,
const std::string& sdp) { const std::string& sdp) {
@ -30,8 +30,7 @@ bool RtspServer::update_source(uint8_t id,
for (unsigned int i = 0; i < sessions_.size(); i++) { for (unsigned int i = 0; i < sessions_.size(); i++) {
auto session = sessions_[i].lock(); auto session = sessions_[i].lock();
if (session != nullptr) { if (session != nullptr) {
ret |= session->announce(id, name, sdp, ret |= session->announce(id, name, sdp, config_->get_ip_addr_str(),
config_->get_ip_addr_str(),
config_->get_rtsp_port()); config_->get_rtsp_port());
} }
} }
@ -46,8 +45,8 @@ void RtspServer::accept() {
unsigned int i = 0; unsigned int i = 0;
for (; i < sessions_.size(); i++) { for (; i < sessions_.size(); i++) {
if (sessions_[i].use_count() == 0) { if (sessions_[i].use_count() == 0) {
auto session = std::make_shared<RtspSession>(config_, auto session = std::make_shared<RtspSession>(
session_manager_, std::move(socket_)); config_, session_manager_, std::move(socket_));
sessions_[i] = session; sessions_[i] = session;
sessions_start_point_[i] = steady_clock::now(); sessions_start_point_[i] = steady_clock::now();
session->start(); session->start();
@ -72,7 +71,8 @@ bool RtspSession::announce(uint8_t id,
const std::string& address, const std::string& address,
uint16_t port) { uint16_t port) {
/* if a describe request is currently not beeing process /* 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()) { if (cseq_ < 0 && source_ids_.find(id) != source_ids_.end()) {
std::string path(std::string("/by-name/") + std::string path(std::string("/by-name/") +
get_node_id(config_->get_ip_addr()) + " " + name); get_node_id(config_->get_ip_addr()) + " " + name);
@ -80,15 +80,16 @@ bool RtspSession::announce(uint8_t id,
ss << "ANNOUNCE rtsp://" << address << ":" << std::to_string(port) ss << "ANNOUNCE rtsp://" << address << ":" << std::to_string(port)
<< httplib::detail::encode_url(path) << " RTSP/1.0\r\n" << httplib::detail::encode_url(path) << " RTSP/1.0\r\n"
<< "User-Agent: aes67-daemon\r\n" << "User-Agent: aes67-daemon\r\n"
<< "connection: Keep-Alive" << "\r\n" << "connection: Keep-Alive"
<< "\r\n"
<< "CSeq: " << announce_cseq_++ << "\r\n" << "CSeq: " << announce_cseq_++ << "\r\n"
<< "Content-Length: " << sdp.length() << "\r\n" << "Content-Length: " << sdp.length() << "\r\n"
<< "Content-Type: application/sdp\r\n" << "Content-Type: application/sdp\r\n"
<< "\r\n" << "\r\n"
<< sdp; << sdp;
BOOST_LOG_TRIVIAL(info) BOOST_LOG_TRIVIAL(info) << "rtsp_server:: "
<< "rtsp_server:: " << "ANNOUNCE for source " << name << " sent to " << "ANNOUNCE for source " << name << " sent to "
<< socket_.remote_endpoint(); << socket_.remote_endpoint();
send_response(ss.str()); send_response(ss.str());
@ -97,7 +98,6 @@ bool RtspSession::announce(uint8_t id,
return false; return false;
} }
bool RtspSession::process_request() { bool RtspSession::process_request() {
/* /*
DESCRIBE rtsp://127.0.0.1:8080/by-name/test RTSP/1.0 DESCRIBE rtsp://127.0.0.1:8080/by-name/test RTSP/1.0
@ -172,8 +172,8 @@ void RtspSession::build_response(const std::string& url) {
return; return;
} }
auto path = std::get<4>(res); auto path = std::get<4>(res);
auto base_path = std::string("/by-name/") + auto base_path =
get_node_id(config_->get_ip_addr()) + " "; std::string("/by-name/") + get_node_id(config_->get_ip_addr()) + " ";
uint8_t id = SessionManager::stream_id_max + 1; uint8_t id = SessionManager::stream_id_max + 1;
if (path.rfind(base_path) != std::string::npos) { if (path.rfind(base_path) != std::string::npos) {
/* extract the source name from path and retrive the id */ /* extract the source name from path and retrive the id */

View File

@ -83,7 +83,8 @@ class RtspSession : public std::enable_shared_from_this<RtspSession> {
class RtspServer { class RtspServer {
public: 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() = delete;
RtspServer(std::shared_ptr<SessionManager> session_manager, RtspServer(std::shared_ptr<SessionManager> session_manager,
@ -105,17 +106,13 @@ class RtspServer {
session_manager_->add_source_observer( session_manager_->add_source_observer(
SessionManager::ObserverType::add_source, SessionManager::ObserverType::add_source,
std::bind(&RtspServer::update_source, this, std::bind(&RtspServer::update_source, this, std::placeholders::_1,
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
std::placeholders::_2,
std::placeholders::_3));
session_manager_->add_source_observer( session_manager_->add_source_observer(
SessionManager::ObserverType::update_source, SessionManager::ObserverType::update_source,
std::bind(&RtspServer::update_source, this, std::bind(&RtspServer::update_source, this, std::placeholders::_1,
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
std::placeholders::_2,
std::placeholders::_3));
return true; return true;
} }
@ -129,7 +126,9 @@ class RtspServer {
private: private:
/* a source was updated */ /* 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(); void accept();
std::mutex mutex_; std::mutex mutex_;

View File

@ -18,15 +18,14 @@
// //
#include <boost/bind.hpp> #include <boost/bind.hpp>
#include "sap.hpp"
#include "sap.hpp"
using namespace boost::asio; using namespace boost::asio;
using namespace boost::asio::ip; using namespace boost::asio::ip;
SAP::SAP(const std::string& sap_mcast_addr)
SAP::SAP(const std::string& sap_mcast_addr) : : addr_(sap_mcast_addr)
addr_(sap_mcast_addr)
// remote_endpoint_(ip::address::from_string(addr_), port) // remote_endpoint_(ip::address::from_string(addr_), port)
{ {
socket_.open(boost::asio::ip::udp::v4()); socket_.open(boost::asio::ip::udp::v4());
@ -92,7 +91,6 @@ bool SAP::receive(bool& is_announce,
io_service_.run_one(); io_service_.run_one();
} while (ec == boost::asio::error::would_block); } while (ec == boost::asio::error::would_block);
if (!ec && length > 4 && (buffer[0] == 0x20 || buffer[0] == 0x24)) { 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 // no reserved, no compress, no encryption

View File

@ -21,6 +21,7 @@
#define _SAP_HPP_ #define _SAP_HPP_
#include <boost/asio.hpp> #include <boost/asio.hpp>
#include "log.hpp" #include "log.hpp"
using namespace boost::asio; using namespace boost::asio;

View File

@ -19,23 +19,24 @@
#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 #define CPPHTTPLIB_READ_TIMEOUT_SECOND 10
#include <httplib.h> #include <httplib.h>
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <boost/property_tree/json_parser.hpp> #include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/ptree.hpp> #include <boost/property_tree/ptree.hpp>
#include <boost/algorithm/string.hpp> #include <chrono>
#include <experimental/map> #include <experimental/map>
#include <iostream> #include <iostream>
#include <chrono>
#include <map> #include <map>
#include <set> #include <set>
#include "json.hpp" #include "json.hpp"
#include "log.hpp" #include "log.hpp"
#include "session_manager.hpp"
#include "utils.hpp"
#include "rtsp_client.hpp" #include "rtsp_client.hpp"
#include "utils.hpp"
#include "session_manager.hpp"
static uint8_t get_codec_word_lenght(const std::string& codec) { static uint8_t get_codec_word_lenght(const std::string& codec) {
@ -324,8 +325,7 @@ std::list<StreamSource> SessionManager::get_sources() const {
StreamSource SessionManager::get_source_(uint8_t id, StreamSource SessionManager::get_source_(uint8_t id,
const StreamInfo& info) const { const StreamInfo& info) const {
return { return {id,
id,
info.enabled, info.enabled,
info.stream.m_cName, info.stream.m_cName,
info.io, info.io,
@ -335,14 +335,12 @@ StreamSource SessionManager::get_source_(uint8_t id,
info.stream.m_byPayloadType, info.stream.m_byPayloadType,
info.stream.m_ucDSCP, info.stream.m_ucDSCP,
info.refclk_ptp_traceable, info.refclk_ptp_traceable,
{ info.stream.m_aui32Routing, info.stream.m_aui32Routing + {info.stream.m_aui32Routing,
info.stream.m_byNbOfChannels } info.stream.m_aui32Routing + info.stream.m_byNbOfChannels}};
};
} }
StreamSink SessionManager::get_sink_(uint8_t id, const StreamInfo& info) const { StreamSink SessionManager::get_sink_(uint8_t id, const StreamInfo& info) const {
return { return {id,
id,
info.stream.m_cName, info.stream.m_cName,
info.io, info.io,
info.sink_use_sdp, info.sink_use_sdp,
@ -350,9 +348,8 @@ StreamSink SessionManager::get_sink_(uint8_t id, const StreamInfo& info) const {
info.sink_sdp, info.sink_sdp,
info.stream.m_ui32PlayOutDelay, info.stream.m_ui32PlayOutDelay,
info.ignore_refclk_gmid, info.ignore_refclk_gmid,
{ info.stream.m_aui32Routing, info.stream.m_aui32Routing + {info.stream.m_aui32Routing,
info.stream.m_byNbOfChannels } info.stream.m_aui32Routing + info.stream.m_byNbOfChannels}};
};
} }
bool SessionManager::load_status() { bool SessionManager::load_status() {
@ -362,8 +359,8 @@ bool SessionManager::load_status() {
std::ifstream jsonstream(config_->get_status_file()); std::ifstream jsonstream(config_->get_status_file());
if (!jsonstream) { if (!jsonstream) {
BOOST_LOG_TRIVIAL(fatal) BOOST_LOG_TRIVIAL(fatal) << "session_manager:: cannot load status file "
<< "session_manager:: cannot load status file " << config_->get_status_file(); << config_->get_status_file();
return false; return false;
} }
@ -409,7 +406,9 @@ static std::array<uint8_t, 6> get_mcast_mac_addr(uint32_t mcast_ip) {
// As defined by IANA, the most significant 24 bits of an IPv4 multicast // 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 // MAC address are 0x01005E. // Bit 25 is 0, and the other 23 bits are the
// least significant 23 bits of an IPv4 multicast address. // least significant 23 bits of an IPv4 multicast address.
return { 0x01, 0x00, 0x5e, return {0x01,
0x00,
0x5e,
static_cast<uint8_t>((mcast_ip >> 16) & 0x7F), static_cast<uint8_t>((mcast_ip >> 16) & 0x7F),
static_cast<uint8_t>(mcast_ip >> 8), static_cast<uint8_t>(mcast_ip >> 8),
static_cast<uint8_t>(mcast_ip)}; static_cast<uint8_t>(mcast_ip)};
@ -474,12 +473,14 @@ std::error_code SessionManager::add_source(const StreamSource& source) {
strncpy(info.stream.m_cCodec, source.codec.c_str(), strncpy(info.stream.m_cCodec, source.codec.c_str(),
sizeof(info.stream.m_cCodec) - 1); sizeof(info.stream.m_cCodec) - 1);
info.stream.m_ui32MaxSamplesPerPacket = source.max_samples_per_packet; 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_uiId = source.id;
info.stream.m_ui32RTCPSrcIP = config_->get_ip_addr(); info.stream.m_ui32RTCPSrcIP = config_->get_ip_addr();
info.stream.m_ui32SrcIP = config_->get_ip_addr(); // only for Source info.stream.m_ui32SrcIP = config_->get_ip_addr(); // only for Source
info.stream.m_ui32DestIP = 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; source.id;
info.stream.m_usSrcPort = config_->get_rtp_port(); info.stream.m_usSrcPort = config_->get_rtp_port();
info.stream.m_usDestPort = config_->get_rtp_port(); info.stream.m_usDestPort = config_->get_rtp_port();
@ -497,16 +498,17 @@ std::error_code SessionManager::add_source(const StreamSource& source) {
std::unique_lock sources_lock(sources_mutex_); std::unique_lock sources_lock(sources_mutex_);
auto const it = sources_.find(source.id); auto const it = sources_.find(source.id);
if (it != sources_.end()) { if (it != sources_.end()) {
BOOST_LOG_TRIVIAL(info) << "session_manager:: source id " BOOST_LOG_TRIVIAL(info)
<< std::to_string(source.id) << " is in use, updating"; << "session_manager:: source id " << std::to_string(source.id)
<< " is in use, updating";
// remove previous stream if enabled // remove previous stream if enabled
if ((*it).second.enabled) { if ((*it).second.enabled) {
(void)driver_->remove_rtp_stream((*it).second.handle); (void)driver_->remove_rtp_stream((*it).second.handle);
on_remove_source((*it).second); on_remove_source((*it).second);
} }
} else if (source_names_.find(source.name) != source_names_.end()) { } else if (source_names_.find(source.name) != source_names_.end()) {
BOOST_LOG_TRIVIAL(error) << "session_manager:: source name " BOOST_LOG_TRIVIAL(error)
<< source.name << " is in use"; << "session_manager:: source name " << source.name << " is in use";
return DaemonErrc::stream_name_in_use; return DaemonErrc::stream_name_in_use;
} }
@ -546,8 +548,8 @@ std::string SessionManager::get_source_sdp_(uint32_t id,
std::ostringstream ss_ptime; std::ostringstream ss_ptime;
ss_ptime.precision(12); ss_ptime.precision(12);
ss_ptime << std::fixed ss_ptime << std::fixed
<< static_cast<double>(info.stream.m_ui32MaxSamplesPerPacket) * 1000 / << static_cast<double>(info.stream.m_ui32MaxSamplesPerPacket) *
static_cast<double>(sample_rate); 1000 / static_cast<double>(sample_rate);
std::string ptime = ss_ptime.str(); 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); ptime.erase(ptime.find_last_not_of("0.") + 1, std::string::npos);
@ -719,8 +721,8 @@ std::error_code SessionManager::add_sink(const StreamSink& sink) {
info.sink_sdp = std::move(sdp); info.sink_sdp = std::move(sdp);
} else { } else {
BOOST_LOG_TRIVIAL(info) << "session_manager:: using SDP " BOOST_LOG_TRIVIAL(info) << "session_manager:: using SDP " << std::endl
<< std::endl << sink.sdp; << sink.sdp;
if (!parse_sdp(sink.sdp, info)) { if (!parse_sdp(sink.sdp, info)) {
return DaemonErrc::cannot_parse_sdp; return DaemonErrc::cannot_parse_sdp;
} }
@ -736,10 +738,10 @@ std::error_code SessionManager::add_sink(const StreamSink& sink) {
info.stream.m_ui32FrameSize = config_->get_max_tic_frame_size(); info.stream.m_ui32FrameSize = config_->get_max_tic_frame_size();
} }
BOOST_LOG_TRIVIAL(info) << "session_manager:: sink frame size " << BOOST_LOG_TRIVIAL(info) << "session_manager:: sink frame size "
info.stream.m_ui32FrameSize; << info.stream.m_ui32FrameSize;
BOOST_LOG_TRIVIAL(info) << "session_manager:: playout delay " << BOOST_LOG_TRIVIAL(info) << "session_manager:: playout delay "
info.stream.m_ui32PlayOutDelay; << info.stream.m_ui32PlayOutDelay;
auto mcast_mac_addr = get_mcast_mac_addr(info.stream.m_ui32DestIP); auto mcast_mac_addr = get_mcast_mac_addr(info.stream.m_ui32DestIP);
std::copy(std::begin(mcast_mac_addr), std::end(mcast_mac_addr), 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_); std::unique_lock sinks_lock(sinks_mutex_);
auto const it = sinks_.find(sink.id); auto const it = sinks_.find(sink.id);
if (it != sinks_.end()) { if (it != sinks_.end()) {
BOOST_LOG_TRIVIAL(info) << "session_manager:: sink id " BOOST_LOG_TRIVIAL(info)
<< std::to_string(sink.id) << " is in use, updating"; << "session_manager:: sink id " << std::to_string(sink.id)
<< " is in use, updating";
// remove previous stream // remove previous stream
(void)driver_->remove_rtp_stream((*it).second.handle); (void)driver_->remove_rtp_stream((*it).second.handle);
on_remove_sink((*it).second); on_remove_sink((*it).second);
} else if (sink_names_.find(sink.name) != sink_names_.end()) { } else if (sink_names_.find(sink.name) != sink_names_.end()) {
BOOST_LOG_TRIVIAL(error) << "session_manager:: sink name " BOOST_LOG_TRIVIAL(error)
<< sink.name << " is in use"; << "session_manager:: sink name " << sink.name << " is in use";
return DaemonErrc::stream_name_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 // check for sources that are no longer announced and send deletion/s
for (auto const& [msg_id_hash, src_addr] : announced_sources_) { for (auto const& [msg_id_hash, src_addr] : announced_sources_) {
// check if this source is no longer announced // check if this source is no longer announced
if (active_sources.find(msg_id_hash) == if (active_sources.find(msg_id_hash) == active_sources.end()) {
active_sources.end()) {
// retrieve deleted source SDP // retrieve deleted source SDP
std::string sdp = get_removed_source_sdp_(msg_id_hash >> 16, src_addr); std::string sdp = get_removed_source_sdp_(msg_id_hash >> 16, src_addr);
// send deletion for this source // send deletion for this source
@ -955,8 +957,8 @@ bool SessionManager::worker() {
while (running_) { while (running_) {
// check if it's time to update the PTP status // check if it's time to update the PTP status
if ((duration_cast<second_t>(steady_clock::now() - ptp_timepoint).count()) if ((duration_cast<second_t>(steady_clock::now() - ptp_timepoint).count()) >
> ptp_interval) { ptp_interval) {
ptp_timepoint = steady_clock::now(); ptp_timepoint = steady_clock::now();
if (driver_->get_ptp_config(ptp_config) || if (driver_->get_ptp_config(ptp_config) ||
driver_->get_ptp_status(ptp_status)) { driver_->get_ptp_status(ptp_status)) {
@ -967,9 +969,9 @@ bool SessionManager::worker() {
char ptp_clock_id[24]; char ptp_clock_id[24];
uint8_t* pui64GMID = reinterpret_cast<uint8_t*>(&ptp_status.ui64GMID); uint8_t* pui64GMID = reinterpret_cast<uint8_t*>(&ptp_status.ui64GMID);
snprintf(ptp_clock_id, sizeof(ptp_clock_id), snprintf(ptp_clock_id, sizeof(ptp_clock_id),
"%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X", "%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X", pui64GMID[0],
pui64GMID[0], pui64GMID[1], pui64GMID[2], pui64GMID[3], pui64GMID[1], pui64GMID[2], pui64GMID[3], pui64GMID[4],
pui64GMID[4], pui64GMID[5], pui64GMID[6], pui64GMID[7]); pui64GMID[5], pui64GMID[6], pui64GMID[7]);
bool ptp_changed_gmid = false; bool ptp_changed_gmid = false;
bool ptp_changed_to_locked = false; bool ptp_changed_to_locked = false;
@ -1005,7 +1007,6 @@ bool SessionManager::worker() {
// end update PTP clock status // 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(); on_ptp_status_locked();
} }
@ -1022,8 +1023,8 @@ bool SessionManager::worker() {
} }
// check if it's time to send sap announcements // check if it's time to send sap announcements
if ((duration_cast<second_t>(steady_clock::now() - sap_timepoint).count()) if ((duration_cast<second_t>(steady_clock::now() - sap_timepoint).count()) >
> sap_interval) { sap_interval) {
sap_timepoint = steady_clock::now(); sap_timepoint = steady_clock::now();
auto sdp_len_sum = process_sap(); auto sdp_len_sum = process_sap();

View File

@ -21,10 +21,10 @@
#define _SESSION_MANAGER_HPP_ #define _SESSION_MANAGER_HPP_
#include <future> #include <future>
#include <list>
#include <map> #include <map>
#include <shared_mutex> #include <shared_mutex>
#include <thread> #include <thread>
#include <list>
#include "config.hpp" #include "config.hpp"
#include "driver_manager.hpp" #include "driver_manager.hpp"
@ -136,8 +136,8 @@ class SessionManager {
uint8_t get_source_id(const std::string& name) const; uint8_t get_source_id(const std::string& name) const;
enum class ObserverType { add_source, remove_source, update_source }; enum class ObserverType { add_source, remove_source, update_source };
using Observer = std::function<bool(uint8_t id, const std::string& name, using Observer = std::function<
const std::string& sdp)>; bool(uint8_t id, const std::string& name, const std::string& sdp)>;
void add_source_observer(ObserverType type, Observer cb); void add_source_observer(ObserverType type, Observer cb);
std::error_code add_sink(const StreamSink& sink); std::error_code add_sink(const StreamSink& sink);

View File

@ -20,5 +20,5 @@
"mdns_enabled": true, "mdns_enabled": true,
"mac_addr": "00:00:00:00:00:00", "mac_addr": "00:00:00:00:00:00",
"ip_addr": "127.0.0.1", "ip_addr": "127.0.0.1",
"node_id": "AES67 daemon d9aca383" "node_id": "AES67 daemon 007f0100"
} }

View File

@ -83,13 +83,8 @@ struct DaemonInstance {
#if defined _MEMORY_CHECK_ #if defined _MEMORY_CHECK_
search_path("valgrind"), search_path("valgrind"),
#endif #endif
"../aes67-daemon", "../aes67-daemon", "-c", "daemon.conf", "-p", "9999", "-i", "lo"
"-c", };
"daemon.conf",
"-p",
"9999",
"-i",
"lo"};
inline static bool ok{false}; inline static bool ok{false};
}; };
@ -259,11 +254,12 @@ struct Client {
"map": [ 0, 1 ], "map": [ 0, 1 ],
)"; )";
std::string json = json1 + std::string json =
json1 +
std::string("\"name\": \"ALSA " + std::to_string(id) + "\",\n") + std::string("\"name\": \"ALSA " + std::to_string(id) + "\",\n") +
std::string("\"source\": \"http://") + std::string("\"source\": \"http://") + g_daemon_address + ":" +
g_daemon_address + ":" + std::to_string(g_daemon_port) + std::to_string(g_daemon_port) + std::string("/api/source/sdp/") +
std::string("/api/source/sdp/") + std::to_string(id) + "\"\n}"; std::to_string(id) + "\"\n}";
std::string url = std::string("/api/sink/") + std::to_string(id); std::string url = std::string("/api/sink/") + std::to_string(id);
auto res = cli_.Put(url.c_str(), json, "application/json"); auto res = cli_.Put(url.c_str(), json, "application/json");
BOOST_REQUIRE_MESSAGE(res != nullptr, "server returned response"); BOOST_REQUIRE_MESSAGE(res != nullptr, "server returned response");
@ -308,7 +304,8 @@ struct Client {
// o=- 56 0 IN IP4 127.0.0.1 // o=- 56 0 IN IP4 127.0.0.1
ids.insert(std::atoi(sap_sdp_.c_str() + 3)); ids.insert(std::atoi(sap_sdp_.c_str() + 3));
BOOST_TEST_MESSAGE("waiting deletion for " + BOOST_TEST_MESSAGE("waiting deletion for " +
std::to_string(g_stream_num_max - ids.size()) + " sources"); std::to_string(g_stream_num_max - ids.size()) +
" sources");
} }
} }
} }
@ -407,7 +404,8 @@ BOOST_AUTO_TEST_CASE(get_config) {
BOOST_CHECK_MESSAGE(ptp_dscp == 46, "config as excepcted"); BOOST_CHECK_MESSAGE(ptp_dscp == 46, "config as excepcted");
BOOST_CHECK_MESSAGE(sap_interval == 1, "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_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(status_file == "", "config as excepcted");
BOOST_CHECK_MESSAGE(interface_name == "lo", "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"); 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); boost::property_tree::read_json(ss, pt);
auto status = pt.get<std::string>("status"); auto status = pt.get<std::string>("status");
auto jitter = pt.get<int>("jitter"); auto jitter = pt.get<int>("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) { 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); boost::property_tree::read_json(fs, pt);
domain = pt.get<int>("ptp_domain"); domain = pt.get<int>("ptp_domain");
dscp = pt.get<int>("ptp_dscp"); dscp = pt.get<int>("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); res = cli.set_ptp_config(0, 46);
BOOST_REQUIRE_MESSAGE(res, "set default ptp config"); BOOST_REQUIRE_MESSAGE(res, "set default ptp config");
} }
@ -469,7 +469,8 @@ BOOST_AUTO_TEST_CASE(add_invalid_source) {
BOOST_AUTO_TEST_CASE(remove_invalid_source) { BOOST_AUTO_TEST_CASE(remove_invalid_source) {
Client cli; 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)); "not removed source " + std::to_string(g_stream_num_max));
BOOST_REQUIRE_MESSAGE(!cli.remove_source(-1), "not removed source -1"); BOOST_REQUIRE_MESSAGE(!cli.remove_source(-1), "not removed source -1");
} }
@ -522,7 +523,8 @@ BOOST_AUTO_TEST_CASE(source_check_sap_browser) {
std::stringstream ss(json.second); std::stringstream ss(json.second);
boost::property_tree::read_json(ss, pt); boost::property_tree::read_json(ss, pt);
BOOST_FOREACH (auto const& v, pt.get_child("remote_sources")) { BOOST_FOREACH (auto const& v, pt.get_child("remote_sources")) {
BOOST_REQUIRE_MESSAGE(v.second.get<std::string>("sdp") == sdp.second, BOOST_REQUIRE_MESSAGE(
v.second.get<std::string>("sdp") == sdp.second,
"returned sap source " + v.second.get<std::string>("id")); "returned sap source " + v.second.get<std::string>("id"));
} }
BOOST_REQUIRE_MESSAGE(cli.remove_source(0), "removed source 0"); BOOST_REQUIRE_MESSAGE(cli.remove_source(0), "removed source 0");
@ -541,24 +543,28 @@ BOOST_AUTO_TEST_CASE(source_check_mdns_browser) {
BOOST_REQUIRE_MESSAGE(cli.add_source(0), "added source 0"); BOOST_REQUIRE_MESSAGE(cli.add_source(0), "added source 0");
auto sdp = cli.get_source_sdp(0); auto sdp = cli.get_source_sdp(0);
BOOST_REQUIRE_MESSAGE(sdp.first, "got 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(); auto json = cli.get_remote_mdns_sources();
BOOST_REQUIRE_MESSAGE(json.first, "got remote mdns sources"); BOOST_REQUIRE_MESSAGE(json.first, "got remote mdns sources");
boost::property_tree::ptree pt; boost::property_tree::ptree pt;
std::stringstream ss(json.second); std::stringstream ss(json.second);
boost::property_tree::read_json(ss, pt); boost::property_tree::read_json(ss, pt);
BOOST_FOREACH (auto const& v, pt.get_child("remote_sources")) { BOOST_FOREACH (auto const& v, pt.get_child("remote_sources")) {
BOOST_REQUIRE_MESSAGE(v.second.get<std::string>("sdp") == sdp.second, BOOST_REQUIRE_MESSAGE(
v.second.get<std::string>("sdp") == sdp.second,
"returned mdns source " + v.second.get<std::string>("id")); "returned mdns source " + v.second.get<std::string>("id"));
} }
BOOST_REQUIRE_MESSAGE(cli.remove_source(0), "removed source 0"); 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) { BOOST_AUTO_TEST_CASE(source_check_mdns_browser_update) {
Client cli; Client cli;
BOOST_REQUIRE_MESSAGE(cli.add_source(0), "added source 0"); 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"); BOOST_REQUIRE_MESSAGE(cli.update_source(0), "updated source 0");
auto sdp = cli.get_source_sdp(0); auto sdp = cli.get_source_sdp(0);
BOOST_REQUIRE_MESSAGE(sdp.first, "got source sdp 0"); BOOST_REQUIRE_MESSAGE(sdp.first, "got source sdp 0");
@ -580,7 +586,8 @@ BOOST_AUTO_TEST_CASE(source_check_mdns_browser_update) {
} while (retry-- && !found); } while (retry-- && !found);
BOOST_REQUIRE_MESSAGE(retry > 0, "remote mdns source updated"); BOOST_REQUIRE_MESSAGE(retry > 0, "remote mdns source updated");
BOOST_REQUIRE_MESSAGE(cli.remove_source(0), "removed source 0"); 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 #endif
@ -737,7 +744,8 @@ BOOST_AUTO_TEST_CASE(add_remove_check_sap_browser_all) {
} }
for (int id = 0; id < g_stream_num_max; id++) { for (int id = 0; id < g_stream_num_max; id++) {
auto sdp = cli.get_source_sdp(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); cli.sap_wait_announcement(id, sdp.second);
} }
boost::property_tree::ptree pt; boost::property_tree::ptree pt;
@ -749,9 +757,12 @@ BOOST_AUTO_TEST_CASE(add_remove_check_sap_browser_all) {
std::stringstream ss(json.second); std::stringstream ss(json.second);
boost::property_tree::read_json(ss, 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()));
} while (pt.get_child("remote_sources").size() != g_stream_num_max && retry--); } while (pt.get_child("remote_sources").size() != g_stream_num_max &&
BOOST_REQUIRE_MESSAGE(pt.get_child("remote_sources").size() == g_stream_num_max, retry--);
"found " + std::to_string(pt.get_child("remote_sources").size()) + " remote sap sources"); 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++) { for (int id = 0; id < g_stream_num_max; id++) {
BOOST_REQUIRE_MESSAGE(cli.add_sink_sdp(id), BOOST_REQUIRE_MESSAGE(cli.add_sink_sdp(id),
std::string("added sink ") + std::to_string(id)); std::string("added sink ") + std::to_string(id));
@ -786,7 +797,8 @@ BOOST_AUTO_TEST_CASE(add_remove_check_sap_browser_all) {
boost::property_tree::read_json(ss2, pt); 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--); } 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++) { for (int id = 0; id < g_stream_num_max; id++) {
BOOST_REQUIRE_MESSAGE(cli.remove_sink(id), BOOST_REQUIRE_MESSAGE(cli.remove_sink(id),
std::string("removed sink ") + std::to_string(id)); std::string("removed sink ") + std::to_string(id));
@ -827,7 +839,8 @@ BOOST_AUTO_TEST_CASE(add_remove_check_mdns_browser_all) {
BOOST_REQUIRE_MESSAGE(cli.remove_source(id), BOOST_REQUIRE_MESSAGE(cli.remove_source(id),
std::string("removed source ") + std::to_string(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++) { for (int id = 0; id < g_stream_num_max; id++) {
BOOST_REQUIRE_MESSAGE(cli.remove_sink(id), BOOST_REQUIRE_MESSAGE(cli.remove_sink(id),
std::string("removed sink ") + std::to_string(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), BOOST_REQUIRE_MESSAGE(cli.remove_source(id),
std::string("removed source ") + std::to_string(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 #endif

View File

@ -18,9 +18,11 @@
// //
// //
#include <boost/format.hpp>
#include "utils.hpp" #include "utils.hpp"
#include <boost/algorithm/string.hpp>
#include <boost/format.hpp>
uint16_t crc16(const uint8_t* p, size_t len) { uint16_t crc16(const uint8_t* p, size_t len) {
uint8_t x; uint8_t x;
uint16_t crc = 0xFFFF; uint16_t crc = 0xFFFF;
@ -78,7 +80,20 @@ std::string get_node_id(uint32_t ip_addr) {
std::stringstream ss; std::stringstream ss;
ip_addr = htonl(ip_addr); ip_addr = htonl(ip_addr);
/* we create an host ID based on the current IP */ /* we create an host ID based on the current IP */
ss << "AES67 daemon " << boost::format("%08x") % ss << "AES67 daemon "
((ip_addr << 16) | (ip_addr >> 16)); << boost::format("%08x") % ((ip_addr << 16) | (ip_addr >> 16));
return ss.str(); 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 "";
}

View File

@ -20,11 +20,11 @@
#ifndef _UTILS_HPP_ #ifndef _UTILS_HPP_
#define _UTILS_HPP_ #define _UTILS_HPP_
#include <iostream>
#include <cstddef>
#include <httplib.h> #include <httplib.h>
#include <cstddef>
#include <iostream>
uint16_t crc16(const uint8_t* p, size_t len); uint16_t crc16(const uint8_t* p, size_t len);
std::tuple<bool /* res */, std::tuple<bool /* res */,
@ -36,4 +36,6 @@ parse_url(const std::string& _url);
std::string get_node_id(uint32_t ip_addr); std::string get_node_id(uint32_t ip_addr);
std::string sdp_get_subject(const std::string& sdp);
#endif #endif