Applied Clang source code formatting to daemon sources
This commit is contained in:
parent
f9a07569f9
commit
098cebd056
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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_;
|
||||||
|
@ -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)
|
||||||
|
@ -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:
|
||||||
|
@ -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 {
|
||||||
|
@ -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:
|
||||||
|
@ -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;
|
||||||
|
@ -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:
|
||||||
|
@ -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");
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;*/
|
||||||
|
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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_
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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};
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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));
|
||||||
|
@ -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;
|
||||||
|
@ -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 */
|
||||||
|
@ -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_;
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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();
|
||||||
|
@ -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);
|
||||||
|
@ -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"
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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 "";
|
||||||
|
}
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user