Fixed a few minor bugs and removed some code smells
This commit is contained in:
parent
580a5d9c12
commit
7bf73823c6
@ -96,6 +96,8 @@ bool Browser::worker() {
|
|||||||
BOOST_LOG_TRIVIAL(debug)
|
BOOST_LOG_TRIVIAL(debug)
|
||||||
<< "browser:: refreshing SAP source " << it->id;
|
<< "browser:: refreshing SAP source " << it->id;
|
||||||
// annoucement, update last seen and announce period
|
// annoucement, update last seen and announce period
|
||||||
|
auto last_update_ =
|
||||||
|
duration_cast<second_t>(steady_clock::now() - startup_).count();
|
||||||
auto upd_source{*it};
|
auto upd_source{*it};
|
||||||
if ((last_update_ - upd_source.last_seen) != 0) {
|
if ((last_update_ - upd_source.last_seen) != 0) {
|
||||||
upd_source.announce_period = last_update_ - upd_source.last_seen;
|
upd_source.announce_period = last_update_ - upd_source.last_seen;
|
||||||
|
@ -57,7 +57,6 @@ class Browser : public MDNSClient {
|
|||||||
Browser() = delete;
|
Browser() = delete;
|
||||||
Browser(const Browser&) = delete;
|
Browser(const Browser&) = delete;
|
||||||
Browser& operator=(const Browser&) = delete;
|
Browser& operator=(const Browser&) = delete;
|
||||||
virtual ~Browser() { terminate(); };
|
|
||||||
|
|
||||||
bool init() override;
|
bool init() override;
|
||||||
bool terminate() override;
|
bool terminate() override;
|
||||||
@ -68,17 +67,17 @@ class Browser : public MDNSClient {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
// singleton, use create() to build
|
// singleton, use create() to build
|
||||||
Browser(std::shared_ptr<Config> config)
|
explicit Browser(std::shared_ptr<Config> config) : MDNSClient(config){};
|
||||||
: MDNSClient(config), startup_(std::chrono::steady_clock::now()){};
|
|
||||||
|
|
||||||
bool worker();
|
bool worker();
|
||||||
|
|
||||||
virtual void on_change_rtsp_source(const std::string& name,
|
void on_change_rtsp_source(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(const std::string& name,
|
void on_remove_rtsp_source(const std::string& name,
|
||||||
const std::string& domain) override;
|
const std::string& domain) override;
|
||||||
|
|
||||||
|
private:
|
||||||
std::future<bool> res_;
|
std::future<bool> res_;
|
||||||
std::atomic_bool running_{false};
|
std::atomic_bool running_{false};
|
||||||
|
|
||||||
@ -99,7 +98,7 @@ class Browser : public MDNSClient {
|
|||||||
|
|
||||||
SAP sap_{config_->get_sap_mcast_addr()};
|
SAP sap_{config_->get_sap_mcast_addr()};
|
||||||
IGMP igmp_;
|
IGMP igmp_;
|
||||||
std::chrono::time_point<std::chrono::steady_clock> startup_;
|
std::chrono::time_point<std::chrono::steady_clock> startup_{std::chrono::steady_clock::now()};
|
||||||
uint32_t last_update_{0}; /* seconds from daemon startup */
|
uint32_t last_update_{0}; /* seconds from daemon startup */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -76,8 +76,7 @@ std::shared_ptr<Config> Config::parse(const std::string& filename,
|
|||||||
config.sap_mcast_addr_ = "224.2.127.254";
|
config.sap_mcast_addr_ = "224.2.127.254";
|
||||||
}
|
}
|
||||||
if (config.ptp_domain_ > 127)
|
if (config.ptp_domain_ > 127)
|
||||||
if (config.ptp_domain_ > 127)
|
config.ptp_domain_ = 0;
|
||||||
config.ptp_domain_ = 0;
|
|
||||||
|
|
||||||
auto [mac_addr, mac_str] = get_interface_mac(config.interface_name_);
|
auto [mac_addr, mac_str] = get_interface_mac(config.interface_name_);
|
||||||
if (mac_str.empty()) {
|
if (mac_str.empty()) {
|
||||||
|
@ -35,7 +35,7 @@ class Config {
|
|||||||
/* attributes retrieved from config json */
|
/* attributes retrieved from config json */
|
||||||
uint16_t get_http_port() const { return http_port_; };
|
uint16_t get_http_port() const { return http_port_; };
|
||||||
uint16_t get_rtsp_port() const { return rtsp_port_; };
|
uint16_t get_rtsp_port() const { return rtsp_port_; };
|
||||||
const std::string get_http_base_dir() const { return http_base_dir_; };
|
const std::string& get_http_base_dir() const { return http_base_dir_; };
|
||||||
int get_log_severity() const { return log_severity_; };
|
int get_log_severity() const { return log_severity_; };
|
||||||
uint32_t get_playout_delay() const { return playout_delay_; };
|
uint32_t get_playout_delay() const { return playout_delay_; };
|
||||||
uint32_t get_tic_frame_size_at_1fs() const { return tic_frame_size_at_1fs_; };
|
uint32_t get_tic_frame_size_at_1fs() const { return tic_frame_size_at_1fs_; };
|
||||||
@ -64,7 +64,7 @@ class Config {
|
|||||||
bool get_daemon_restart() const { return daemon_restart_; };
|
bool get_daemon_restart() const { return daemon_restart_; };
|
||||||
bool get_driver_restart() const { return driver_restart_; };
|
bool get_driver_restart() const { return driver_restart_; };
|
||||||
bool get_mdns_enabled() const { return mdns_enabled_; };
|
bool get_mdns_enabled() const { return mdns_enabled_; };
|
||||||
int get_interface_idx() { return interface_idx_; };
|
int get_interface_idx() const { return interface_idx_; };
|
||||||
const std::string& get_ptp_status_script() const {
|
const std::string& get_ptp_status_script() const {
|
||||||
return ptp_status_script_;
|
return ptp_status_script_;
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ void DriverHandler::send(enum MT_ALSA_msg_id id,
|
|||||||
NetlinkClient& client,
|
NetlinkClient& client,
|
||||||
uint8_t* buffer,
|
uint8_t* buffer,
|
||||||
size_t data_size,
|
size_t data_size,
|
||||||
const uint8_t* data) {
|
const uint8_t* data) const {
|
||||||
struct MT_ALSA_msg alsa_msg;
|
struct MT_ALSA_msg alsa_msg;
|
||||||
memset(&alsa_msg, 0, sizeof(alsa_msg));
|
memset(&alsa_msg, 0, sizeof(alsa_msg));
|
||||||
alsa_msg.id = id;
|
alsa_msg.id = id;
|
||||||
@ -143,7 +143,7 @@ bool DriverHandler::terminate(const Config& /* config */) {
|
|||||||
void DriverHandler::send_command(enum MT_ALSA_msg_id id,
|
void DriverHandler::send_command(enum MT_ALSA_msg_id id,
|
||||||
size_t data_size,
|
size_t data_size,
|
||||||
const uint8_t* data) {
|
const uint8_t* data) {
|
||||||
std::lock_guard<std::mutex> lock(mutex_);
|
std::scoped_lock<std::mutex> lock{mutex_};
|
||||||
if (data_size > max_payload) {
|
if (data_size > max_payload) {
|
||||||
on_command_error(id, DaemonErrc::send_invalid_size);
|
on_command_error(id, DaemonErrc::send_invalid_size);
|
||||||
return;
|
return;
|
||||||
|
@ -37,7 +37,7 @@ class DriverHandler {
|
|||||||
static constexpr size_t buffer_size =
|
static constexpr size_t buffer_size =
|
||||||
NLMSG_SPACE(max_payload) + sizeof(struct MT_ALSA_msg);
|
NLMSG_SPACE(max_payload) + sizeof(struct MT_ALSA_msg);
|
||||||
|
|
||||||
DriverHandler(){};
|
DriverHandler() = default;
|
||||||
DriverHandler(const DriverHandler&) = delete;
|
DriverHandler(const DriverHandler&) = delete;
|
||||||
DriverHandler& operator=(const DriverHandler&) = delete;
|
DriverHandler& operator=(const DriverHandler&) = delete;
|
||||||
virtual ~DriverHandler(){};
|
virtual ~DriverHandler(){};
|
||||||
@ -67,7 +67,7 @@ class DriverHandler {
|
|||||||
NetlinkClient& client,
|
NetlinkClient& client,
|
||||||
uint8_t* buffer,
|
uint8_t* buffer,
|
||||||
size_t data_size,
|
size_t data_size,
|
||||||
const uint8_t* data);
|
const uint8_t* data) const;
|
||||||
bool event_receiver();
|
bool event_receiver();
|
||||||
|
|
||||||
std::future<bool> res_;
|
std::future<bool> res_;
|
||||||
|
@ -75,7 +75,7 @@ bool DriverManager::init(const Config& config) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
sample_rate = config.get_sample_rate();
|
sample_rate_ = config.get_sample_rate();
|
||||||
|
|
||||||
TPTPConfig ptp_config;
|
TPTPConfig ptp_config;
|
||||||
ptp_config.ui8Domain = config.get_ptp_domain();
|
ptp_config.ui8Domain = config.get_ptp_domain();
|
||||||
@ -287,39 +287,41 @@ void DriverManager::on_event(enum MT_ALSA_msg_id id,
|
|||||||
break;
|
break;
|
||||||
case MT_ALSA_Msg_SetMasterOutputVolume:
|
case MT_ALSA_Msg_SetMasterOutputVolume:
|
||||||
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 " << output_volume;
|
<< "driver_manager:: event SetMasterOutputVolume "
|
||||||
|
<< output_volume_;
|
||||||
}
|
}
|
||||||
resp_size = 0;
|
resp_size = 0;
|
||||||
break;
|
break;
|
||||||
case MT_ALSA_Msg_SetMasterOutputSwitch:
|
case MT_ALSA_Msg_SetMasterOutputSwitch:
|
||||||
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 " << output_switch;
|
<< "driver_manager:: event SetMasterOutputSwitch "
|
||||||
|
<< 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)
|
BOOST_LOG_TRIVIAL(info)
|
||||||
<< "driver_manager:: event SetSampleRate " << sample_rate;
|
<< "driver_manager:: event SetSampleRate " << sample_rate_;
|
||||||
}
|
}
|
||||||
resp_size = 0;
|
resp_size = 0;
|
||||||
break;
|
break;
|
||||||
case MT_ALSA_Msg_GetMasterOutputVolume:
|
case MT_ALSA_Msg_GetMasterOutputVolume:
|
||||||
resp_size = sizeof(int32_t);
|
resp_size = sizeof(int32_t);
|
||||||
memcpy(resp, &output_volume, resp_size);
|
memcpy(resp, &output_volume_, resp_size);
|
||||||
BOOST_LOG_TRIVIAL(info)
|
BOOST_LOG_TRIVIAL(info)
|
||||||
<< "driver_manager:: event GetMasterOutputVolume " << output_volume;
|
<< "driver_manager:: event GetMasterOutputVolume " << output_volume_;
|
||||||
break;
|
break;
|
||||||
case MT_ALSA_Msg_GetMasterOutputSwitch:
|
case MT_ALSA_Msg_GetMasterOutputSwitch:
|
||||||
resp_size = sizeof(int32_t);
|
resp_size = sizeof(int32_t);
|
||||||
memcpy(resp, &output_switch, resp_size);
|
memcpy(resp, &output_switch_, resp_size);
|
||||||
BOOST_LOG_TRIVIAL(info)
|
BOOST_LOG_TRIVIAL(info)
|
||||||
<< "driver_manager:: event GetMasterOutputSwitch " << output_switch;
|
<< "driver_manager:: event GetMasterOutputSwitch " << output_switch_;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
BOOST_LOG_TRIVIAL(error) << "driver_manager:: unknown event "
|
BOOST_LOG_TRIVIAL(error) << "driver_manager:: unknown event "
|
||||||
|
@ -53,13 +53,13 @@ class DriverManager : public DriverHandler {
|
|||||||
std::error_code get_number_of_inputs(int32_t& inputs);
|
std::error_code get_number_of_inputs(int32_t& inputs);
|
||||||
std::error_code get_number_of_outputs(int32_t& outputs);
|
std::error_code get_number_of_outputs(int32_t& outputs);
|
||||||
|
|
||||||
int32_t get_current_output_volume() { return output_volume; };
|
int32_t get_current_output_volume() const { return output_volume_; };
|
||||||
int32_t get_current_output_switch() { return output_switch; };
|
int32_t get_current_output_switch() const { return output_switch_; };
|
||||||
uint32_t get_current_sample_rate() { return sample_rate; };
|
uint32_t get_current_sample_rate() const { return sample_rate_; };
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// singleton, use create to build
|
// singleton, use create to build
|
||||||
DriverManager(){};
|
DriverManager() = default;
|
||||||
|
|
||||||
// these are used in init/terminate
|
// these are used in init/terminate
|
||||||
std::error_code hello();
|
std::error_code hello();
|
||||||
@ -79,12 +79,13 @@ class DriverManager : public DriverHandler {
|
|||||||
const uint8_t* req = nullptr) override;
|
const uint8_t* req = nullptr) override;
|
||||||
void on_event_error(enum MT_ALSA_msg_id id, std::error_code error) override;
|
void on_event_error(enum MT_ALSA_msg_id id, std::error_code error) override;
|
||||||
|
|
||||||
|
private:
|
||||||
std::error_code retcode_;
|
std::error_code retcode_;
|
||||||
uint8_t recv_data_[NLMSG_SPACE(max_payload)]{0};
|
uint8_t recv_data_[NLMSG_SPACE(max_payload)]{0};
|
||||||
|
|
||||||
int32_t output_volume{-20};
|
int32_t output_volume_{-20};
|
||||||
int32_t output_switch{0};
|
int32_t output_switch_{0};
|
||||||
uint32_t sample_rate{0};
|
uint32_t sample_rate_{0};
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -120,8 +120,9 @@ std::error_code DriverManager::add_rtp_stream(
|
|||||||
uint64_t& stream_handle) {
|
uint64_t& stream_handle) {
|
||||||
stream_handle = ++g_handle;
|
stream_handle = ++g_handle;
|
||||||
handles_.insert(stream_handle);
|
handles_.insert(stream_handle);
|
||||||
BOOST_LOG_TRIVIAL(info) << "fake_driver_manager:: add RTP stream success handle "
|
BOOST_LOG_TRIVIAL(info)
|
||||||
<< stream_handle;
|
<< "fake_driver_manager:: add RTP stream success handle "
|
||||||
|
<< stream_handle;
|
||||||
return std::error_code{};
|
return std::error_code{};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,7 +171,8 @@ std::error_code DriverManager::set_playout_delay(int32_t delay) {
|
|||||||
|
|
||||||
std::error_code DriverManager::get_sample_rate(uint32_t& sample_rate) {
|
std::error_code DriverManager::get_sample_rate(uint32_t& sample_rate) {
|
||||||
sample_rate = sample_rate_;
|
sample_rate = sample_rate_;
|
||||||
BOOST_LOG_TRIVIAL(info) << "fake_driver_manager:: sample rate " << sample_rate;
|
BOOST_LOG_TRIVIAL(info) << "fake_driver_manager:: sample rate "
|
||||||
|
<< sample_rate;
|
||||||
return std::error_code{};
|
return std::error_code{};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
using namespace httplib;
|
using namespace httplib;
|
||||||
|
|
||||||
static inline void set_headers(Response& res,
|
static inline void set_headers(Response& res,
|
||||||
const std::string content_type = "") {
|
const std::string& content_type = "") {
|
||||||
res.set_header("Access-Control-Allow-Methods",
|
res.set_header("Access-Control-Allow-Methods",
|
||||||
"GET, POST, PUT, DELETE, OPTIONS");
|
"GET, POST, PUT, DELETE, OPTIONS");
|
||||||
res.set_header("Access-Control-Allow-Origin", "*");
|
res.set_header("Access-Control-Allow-Origin", "*");
|
||||||
@ -57,7 +57,6 @@ static inline int get_http_error_status(const std::error_code& code) {
|
|||||||
|
|
||||||
static inline std::string get_http_error_message(const std::error_code& code) {
|
static inline std::string get_http_error_message(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();
|
||||||
}
|
}
|
||||||
|
@ -29,9 +29,9 @@
|
|||||||
class HttpServer {
|
class HttpServer {
|
||||||
public:
|
public:
|
||||||
HttpServer() = delete;
|
HttpServer() = delete;
|
||||||
HttpServer(std::shared_ptr<SessionManager> session_manager,
|
explicit 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), browser_(browser), config_(config){};
|
: session_manager_(session_manager), browser_(browser), config_(config){};
|
||||||
bool init();
|
bool init();
|
||||||
bool terminate();
|
bool terminate();
|
||||||
|
@ -41,11 +41,11 @@ 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 =
|
uint32_t mcast_ip_addr =
|
||||||
ip::address_v4::from_string(mcast_ip.c_str()).to_ulong();
|
ip::address_v4::from_string(mcast_ip.c_str()).to_ulong();
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::scoped_lock<std::mutex> lock{mutex};
|
||||||
|
|
||||||
auto it = mcast_ref.find(mcast_ip_addr);
|
auto it = mcast_ref.find(mcast_ip_addr);
|
||||||
if (it != mcast_ref.end() && (*it).second > 0) {
|
if (it != mcast_ref.end() && (*it).second > 0) {
|
||||||
mcast_ref[mcast_ip_addr]++;
|
(*it).second++;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,14 +76,14 @@ class IGMP {
|
|||||||
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 =
|
uint32_t mcast_ip_addr =
|
||||||
ip::address_v4::from_string(mcast_ip.c_str()).to_ulong();
|
ip::address_v4::from_string(mcast_ip.c_str()).to_ulong();
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::scoped_lock<std::mutex> lock{mutex};
|
||||||
|
|
||||||
auto it = mcast_ref.find(mcast_ip_addr);
|
auto it = mcast_ref.find(mcast_ip_addr);
|
||||||
if (it == mcast_ref.end() || (*it).second == 0) {
|
if (it == mcast_ref.end() || (*it).second == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (--mcast_ref[mcast_ip_addr] > 0) {
|
if (--(*it).second > 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ std::pair<std::array<uint8_t, 6>, std::string> get_mac_from_arp_cache(
|
|||||||
std::vector<std::string> tokens;
|
std::vector<std::string> tokens;
|
||||||
|
|
||||||
std::getline(stream, line);
|
std::getline(stream, line);
|
||||||
if (line.find(ip)) {
|
if (line.find(ip) == std::string::npos) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
boost::split(tokens, line, boost::is_any_of(" "), boost::token_compress_on);
|
boost::split(tokens, line, boost::is_any_of(" "), boost::token_compress_on);
|
||||||
@ -139,8 +139,8 @@ std::pair<std::array<uint8_t, 6>, std::string> get_mac_from_arp_cache(
|
|||||||
int j = 0;
|
int j = 0;
|
||||||
bool check = false;
|
bool check = false;
|
||||||
for (auto const& item : vec) {
|
for (auto const& item : vec) {
|
||||||
mac[j] = strtol(item.c_str(), NULL, 16);
|
mac[j] = strtol(item.c_str(), nullptr, 16);
|
||||||
check |= mac[j];
|
check = check | (mac[j] != 0);
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
if (check) {
|
if (check) {
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
#include "json.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\?#-]?");
|
||||||
return std::regex_replace(s, html_regex, "");
|
return std::regex_replace(s, html_regex, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ void MDNSClient::resolve_callback(AvahiServiceResolver* r,
|
|||||||
(mdns.config_->get_interface_name() != "lo")) ||
|
(mdns.config_->get_interface_name() != "lo")) ||
|
||||||
((flags & AVAHI_LOOKUP_RESULT_LOCAL) &&
|
((flags & AVAHI_LOOKUP_RESULT_LOCAL) &&
|
||||||
(mdns.config_->get_interface_name() == "lo"))) {
|
(mdns.config_->get_interface_name() == "lo"))) {
|
||||||
std::lock_guard<std::mutex> lock(mdns.sources_res_mutex_);
|
std::scoped_lock<std::mutex> lock{mdns.sources_res_mutex_};
|
||||||
|
|
||||||
/* 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(
|
||||||
@ -153,7 +153,7 @@ void MDNSClient::browse_callback(AvahiServiceBrowser* b,
|
|||||||
<< avahi_strerror(avahi_client_errno(mdns.client_.get()));
|
<< avahi_strerror(avahi_client_errno(mdns.client_.get()));
|
||||||
} else {
|
} else {
|
||||||
/* add the resolver to the active pool */
|
/* add the resolver to the active pool */
|
||||||
mdns.active_resolvers.insert({name, domain});
|
mdns.active_resolvers.emplace(name, domain);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -244,7 +244,7 @@ bool MDNSClient::init() {
|
|||||||
|
|
||||||
void MDNSClient::process_results() {
|
void MDNSClient::process_results() {
|
||||||
#ifdef _USE_AVAHI_
|
#ifdef _USE_AVAHI_
|
||||||
std::lock_guard<std::mutex> lock(sources_res_mutex_);
|
std::scoped_lock<std::mutex> lock{sources_res_mutex_};
|
||||||
/* remove all completed results and populate remote sources list */
|
/* remove all completed results and populate remote sources list */
|
||||||
sources_res_.remove_if([](auto& result) {
|
sources_res_.remove_if([](auto& result) {
|
||||||
if (!result.valid()) {
|
if (!result.valid()) {
|
||||||
@ -269,7 +269,7 @@ bool MDNSClient::terminate() {
|
|||||||
RtspClient::stop_all();
|
RtspClient::stop_all();
|
||||||
#ifdef _USE_AVAHI_
|
#ifdef _USE_AVAHI_
|
||||||
/* wait for all pending results and remove from list */
|
/* wait for all pending results and remove from list */
|
||||||
std::lock_guard<std::mutex> lock(sources_res_mutex_);
|
std::scoped_lock<std::mutex> lock{sources_res_mutex_};
|
||||||
BOOST_LOG_TRIVIAL(info) << "mdns_client:: waiting for "
|
BOOST_LOG_TRIVIAL(info) << "mdns_client:: waiting for "
|
||||||
<< sources_res_.size() << " RTSP clients";
|
<< sources_res_.size() << " RTSP clients";
|
||||||
sources_res_.remove_if([](auto& result) {
|
sources_res_.remove_if([](auto& result) {
|
||||||
|
@ -43,7 +43,7 @@ class MDNSClient {
|
|||||||
MDNSClient() = delete;
|
MDNSClient() = delete;
|
||||||
MDNSClient(const MDNSClient&) = delete;
|
MDNSClient(const MDNSClient&) = delete;
|
||||||
MDNSClient& operator=(const MDNSClient&) = delete;
|
MDNSClient& operator=(const MDNSClient&) = delete;
|
||||||
virtual ~MDNSClient() { terminate(); };
|
virtual ~MDNSClient() = default;
|
||||||
|
|
||||||
virtual bool init();
|
virtual bool init();
|
||||||
virtual bool terminate();
|
virtual bool terminate();
|
||||||
@ -55,22 +55,6 @@ class MDNSClient {
|
|||||||
virtual void on_remove_rtsp_source(const std::string& name,
|
virtual void on_remove_rtsp_source(const std::string& name,
|
||||||
const std::string& domain){};
|
const std::string& domain){};
|
||||||
|
|
||||||
void process_results();
|
|
||||||
std::list<std::future<void> > sources_res_;
|
|
||||||
std::mutex sources_res_mutex_;
|
|
||||||
|
|
||||||
std::atomic_bool running_{false};
|
|
||||||
std::shared_ptr<Config> config_;
|
|
||||||
|
|
||||||
#ifdef _USE_AVAHI_
|
|
||||||
/* order is important here */
|
|
||||||
std::unique_ptr<AvahiThreadedPoll, decltype(&avahi_threaded_poll_free)> poll_{
|
|
||||||
nullptr, &avahi_threaded_poll_free};
|
|
||||||
std::unique_ptr<AvahiClient, decltype(&avahi_client_free)> client_{
|
|
||||||
nullptr, &avahi_client_free};
|
|
||||||
std::unique_ptr<AvahiServiceBrowser, decltype(&avahi_service_browser_free)>
|
|
||||||
sb_{nullptr, &avahi_service_browser_free};
|
|
||||||
|
|
||||||
static void resolve_callback(AvahiServiceResolver* r,
|
static void resolve_callback(AvahiServiceResolver* r,
|
||||||
AvahiIfIndex interface,
|
AvahiIfIndex interface,
|
||||||
AvahiProtocol protocol,
|
AvahiProtocol protocol,
|
||||||
@ -97,9 +81,26 @@ class MDNSClient {
|
|||||||
AvahiClientState state,
|
AvahiClientState state,
|
||||||
void* userdata);
|
void* userdata);
|
||||||
|
|
||||||
|
void process_results();
|
||||||
|
|
||||||
|
std::shared_ptr<Config> config_;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::list<std::future<void> > sources_res_;
|
||||||
|
std::mutex sources_res_mutex_;
|
||||||
|
|
||||||
|
std::atomic_bool running_{false};
|
||||||
|
|
||||||
|
#ifdef _USE_AVAHI_
|
||||||
|
/* order is important here */
|
||||||
|
std::unique_ptr<AvahiThreadedPoll, decltype(&avahi_threaded_poll_free)> poll_{
|
||||||
|
nullptr, &avahi_threaded_poll_free};
|
||||||
|
std::unique_ptr<AvahiClient, decltype(&avahi_client_free)> client_{
|
||||||
|
nullptr, &avahi_client_free};
|
||||||
|
std::unique_ptr<AvahiServiceBrowser, decltype(&avahi_service_browser_free)>
|
||||||
|
sb_{nullptr, &avahi_service_browser_free};
|
||||||
std::set<std::pair<std::string /*name*/, std::string /*domain */> >
|
std::set<std::pair<std::string /*name*/, std::string /*domain */> >
|
||||||
active_resolvers;
|
active_resolvers;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
#ifdef _USE_AVAHI_
|
#ifdef _USE_AVAHI_
|
||||||
struct AvahiLockGuard {
|
struct AvahiLockGuard {
|
||||||
AvahiLockGuard() = delete;
|
AvahiLockGuard() = delete;
|
||||||
AvahiLockGuard(AvahiThreadedPoll* poll) : poll_(poll) {
|
explicit AvahiLockGuard(AvahiThreadedPoll* poll) : poll_(poll) {
|
||||||
if (poll_ != nullptr) {
|
if (poll_ != nullptr) {
|
||||||
avahi_threaded_poll_lock(poll_);
|
avahi_threaded_poll_lock(poll_);
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ class MDNSServer {
|
|||||||
MDNSServer() = delete;
|
MDNSServer() = delete;
|
||||||
MDNSServer(const MDNSServer&) = delete;
|
MDNSServer(const MDNSServer&) = delete;
|
||||||
MDNSServer& operator=(const MDNSServer&) = delete;
|
MDNSServer& operator=(const MDNSServer&) = delete;
|
||||||
virtual ~MDNSServer() { terminate(); };
|
virtual ~MDNSServer() = default;
|
||||||
|
|
||||||
virtual bool init();
|
virtual bool init();
|
||||||
virtual bool terminate();
|
virtual bool terminate();
|
||||||
@ -55,6 +55,16 @@ class MDNSServer {
|
|||||||
bool remove_service(const std::string& name);
|
bool remove_service(const std::string& name);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
static void entry_group_callback(AvahiEntryGroup* g,
|
||||||
|
AvahiEntryGroupState state,
|
||||||
|
void* userdata);
|
||||||
|
static void client_callback(AvahiClient* c,
|
||||||
|
AvahiClientState state,
|
||||||
|
void* userdata);
|
||||||
|
|
||||||
|
bool create_services(AvahiClient* client);
|
||||||
|
|
||||||
|
private:
|
||||||
std::atomic_bool running_{false};
|
std::atomic_bool running_{false};
|
||||||
std::shared_ptr<SessionManager> session_manager_;
|
std::shared_ptr<SessionManager> session_manager_;
|
||||||
std::shared_ptr<Config> config_;
|
std::shared_ptr<Config> config_;
|
||||||
@ -72,14 +82,6 @@ class MDNSServer {
|
|||||||
std::unique_ptr<AvahiClient, decltype(&avahi_client_free)> client_{
|
std::unique_ptr<AvahiClient, decltype(&avahi_client_free)> client_{
|
||||||
nullptr, &avahi_client_free};
|
nullptr, &avahi_client_free};
|
||||||
|
|
||||||
static void entry_group_callback(AvahiEntryGroup* g,
|
|
||||||
AvahiEntryGroupState state,
|
|
||||||
void* userdata);
|
|
||||||
static void client_callback(AvahiClient* c,
|
|
||||||
AvahiClientState state,
|
|
||||||
void* userdata);
|
|
||||||
|
|
||||||
bool create_services(AvahiClient* client);
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -26,62 +26,55 @@
|
|||||||
template <typename Protocol>
|
template <typename Protocol>
|
||||||
class nl_endpoint {
|
class nl_endpoint {
|
||||||
private:
|
private:
|
||||||
sockaddr_nl sockaddr{.nl_family = AF_NETLINK};
|
sockaddr_nl sockaddr_{.nl_family = AF_NETLINK};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using protocol_type = Protocol;
|
using protocol_type = Protocol;
|
||||||
using data_type = boost::asio::detail::socket_addr_type;
|
using data_type = boost::asio::detail::socket_addr_type;
|
||||||
|
|
||||||
nl_endpoint() {
|
nl_endpoint() {
|
||||||
sockaddr.nl_groups = 0;
|
sockaddr_.nl_groups = 0;
|
||||||
sockaddr.nl_pid = getpid();
|
sockaddr_.nl_pid = getpid();
|
||||||
}
|
}
|
||||||
|
|
||||||
nl_endpoint(int group, int pid = getpid()) {
|
nl_endpoint(int group, int pid = getpid()) {
|
||||||
sockaddr.nl_groups = group;
|
sockaddr_.nl_groups = group;
|
||||||
sockaddr.nl_pid = pid;
|
sockaddr_.nl_pid = pid;
|
||||||
}
|
|
||||||
|
|
||||||
nl_endpoint(const nl_endpoint& other) { sockaddr = other.sockaddr; }
|
|
||||||
|
|
||||||
nl_endpoint& operator=(const nl_endpoint& other) {
|
|
||||||
sockaddr = other.sockaddr;
|
|
||||||
return *this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protocol_type protocol() const { return protocol_type(); }
|
protocol_type protocol() const { return protocol_type(); }
|
||||||
|
|
||||||
data_type* data() { return reinterpret_cast<struct sockaddr*>(&sockaddr); }
|
data_type* data() { return reinterpret_cast<struct sockaddr*>(&sockaddr_); }
|
||||||
|
|
||||||
const data_type* data() const {
|
const data_type* data() const {
|
||||||
return reinterpret_cast<const struct sockaddr*>(&sockaddr);
|
return reinterpret_cast<const struct sockaddr*>(&sockaddr_);
|
||||||
}
|
}
|
||||||
|
|
||||||
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_); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class nl_protocol {
|
class nl_protocol {
|
||||||
public:
|
public:
|
||||||
nl_protocol() { proto = 0; }
|
nl_protocol() : proto_(0) {}
|
||||||
|
|
||||||
explicit nl_protocol(int proto) { this->proto = proto; }
|
explicit nl_protocol(int proto) : proto_(proto) {}
|
||||||
|
|
||||||
int type() const { return SOCK_RAW; }
|
int type() const { return SOCK_RAW; }
|
||||||
|
|
||||||
int protocol() const { return proto; }
|
int protocol() const { return proto_; }
|
||||||
|
|
||||||
int family() const { return PF_NETLINK; }
|
int family() const { return PF_NETLINK; }
|
||||||
|
|
||||||
typedef nl_endpoint<nl_protocol> endpoint;
|
using endpoint = nl_endpoint<nl_protocol>;
|
||||||
typedef boost::asio::basic_raw_socket<nl_protocol> socket;
|
using socket = boost::asio::basic_raw_socket<nl_protocol>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int proto;
|
int proto_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -98,14 +98,13 @@ struct RtspActiveClientRemover {
|
|||||||
domain_(domain),
|
domain_(domain),
|
||||||
wait_for_updates_(wait_for_updates) {
|
wait_for_updates_(wait_for_updates) {
|
||||||
if (stream_ != nullptr && wait_for_updates_) {
|
if (stream_ != nullptr && wait_for_updates_) {
|
||||||
RtspClient::g_mutex.lock();
|
std::scoped_lock<std::mutex> lock{RtspClient::g_mutex};
|
||||||
RtspClient::g_active_clients[{name_, domain_}] = stream_;
|
RtspClient::g_active_clients[{name_, domain_}] = stream_;
|
||||||
RtspClient::g_mutex.unlock();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
~RtspActiveClientRemover() {
|
~RtspActiveClientRemover() {
|
||||||
if (stream_ != nullptr && wait_for_updates_) {
|
if (stream_ != nullptr && wait_for_updates_) {
|
||||||
std::lock_guard<std::mutex> lock(RtspClient::g_mutex);
|
std::scoped_lock<std::mutex> lock{RtspClient::g_mutex};
|
||||||
auto it = RtspClient::g_active_clients.find({name_, domain_});
|
auto it = RtspClient::g_active_clients.find({name_, domain_});
|
||||||
if (it != RtspClient::g_active_clients.end() && it->second == stream_) {
|
if (it != RtspClient::g_active_clients.end() && it->second == stream_) {
|
||||||
RtspClient::g_active_clients.erase(it);
|
RtspClient::g_active_clients.erase(it);
|
||||||
@ -120,13 +119,14 @@ struct RtspActiveClientRemover {
|
|||||||
bool wait_for_updates_{false};
|
bool wait_for_updates_{false};
|
||||||
};
|
};
|
||||||
|
|
||||||
std::pair<bool, RtspSource> RtspClient::process(RtspClient::Observer callback,
|
std::pair<bool, RtspSource> RtspClient::process(
|
||||||
const std::string& name,
|
const RtspClient::Observer& callback,
|
||||||
const std::string& domain,
|
const std::string& name,
|
||||||
const std::string& path,
|
const std::string& domain,
|
||||||
const std::string& address,
|
const std::string& path,
|
||||||
const std::string& port,
|
const std::string& address,
|
||||||
bool wait_for_updates) {
|
const std::string& port,
|
||||||
|
bool wait_for_updates) {
|
||||||
RtspSource rtsp_source;
|
RtspSource rtsp_source;
|
||||||
ip::tcp::iostream s;
|
ip::tcp::iostream s;
|
||||||
RtspActiveClientRemover clientRemover(&s, name, domain, wait_for_updates);
|
RtspActiveClientRemover clientRemover(&s, name, domain, wait_for_updates);
|
||||||
@ -258,9 +258,9 @@ std::pair<bool, RtspSource> RtspClient::process(RtspClient::Observer callback,
|
|||||||
if (std::get<0>(res)) {
|
if (std::get<0>(res)) {
|
||||||
/* if we find a valid announced source name we use it
|
/* if we find a valid announced source name we use it
|
||||||
* otherwise we try from SDP file or we use the mDNS name */
|
* otherwise we try from SDP file or we use the mDNS name */
|
||||||
auto path = std::get<4>(res);
|
const auto& lpath = std::get<4>(res);
|
||||||
if (path.rfind("/by-name/") != std::string::npos) {
|
if (path.rfind("/by-name/") != std::string::npos) {
|
||||||
announced_name = path.substr(9);
|
announced_name = lpath.substr(9);
|
||||||
BOOST_LOG_TRIVIAL(debug)
|
BOOST_LOG_TRIVIAL(debug)
|
||||||
<< "rtsp_client:: found announced name " << announced_name;
|
<< "rtsp_client:: found announced name " << announced_name;
|
||||||
}
|
}
|
||||||
@ -279,7 +279,7 @@ std::pair<bool, RtspSource> RtspClient::process(RtspClient::Observer callback,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RtspClient::stop(const std::string& name, const std::string& domain) {
|
void RtspClient::stop(const std::string& name, const std::string& domain) {
|
||||||
std::lock_guard<std::mutex> lock(g_mutex);
|
std::scoped_lock<std::mutex> lock{g_mutex};
|
||||||
auto it = g_active_clients.find({name, domain});
|
auto it = g_active_clients.find({name, domain});
|
||||||
if (it != g_active_clients.end()) {
|
if (it != g_active_clients.end()) {
|
||||||
BOOST_LOG_TRIVIAL(info)
|
BOOST_LOG_TRIVIAL(info)
|
||||||
@ -294,12 +294,12 @@ void RtspClient::stop(const std::string& name, const std::string& domain) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool RtspClient::is_active(const std::string& name, const std::string& domain) {
|
bool RtspClient::is_active(const std::string& name, const std::string& domain) {
|
||||||
std::lock_guard<std::mutex> lock(g_mutex);
|
std::scoped_lock<std::mutex> lock{g_mutex};
|
||||||
return g_active_clients.find({name, domain}) != g_active_clients.end();
|
return g_active_clients.find({name, domain}) != g_active_clients.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RtspClient::stop_all() {
|
void RtspClient::stop_all() {
|
||||||
std::lock_guard<std::mutex> lock(g_mutex);
|
std::scoped_lock<std::mutex> lock{g_mutex};
|
||||||
auto it = g_active_clients.begin();
|
auto it = g_active_clients.begin();
|
||||||
while (it != g_active_clients.end()) {
|
while (it != g_active_clients.end()) {
|
||||||
BOOST_LOG_TRIVIAL(info) << "rtsp_client:: stopping client "
|
BOOST_LOG_TRIVIAL(info) << "rtsp_client:: stopping client "
|
||||||
|
@ -41,7 +41,7 @@ class RtspClient {
|
|||||||
const std::string& domain,
|
const std::string& domain,
|
||||||
const RtspSource& source)>;
|
const RtspSource& source)>;
|
||||||
|
|
||||||
static std::pair<bool, RtspSource> process(Observer callback,
|
static std::pair<bool, RtspSource> process(const Observer& callback,
|
||||||
const std::string& name,
|
const std::string& name,
|
||||||
const std::string& domain,
|
const std::string& domain,
|
||||||
const std::string& path,
|
const std::string& path,
|
||||||
@ -57,11 +57,11 @@ class RtspClient {
|
|||||||
const std::string& address,
|
const std::string& address,
|
||||||
const std::string& port = dft_port);
|
const std::string& port = dft_port);
|
||||||
|
|
||||||
inline static std::atomic<uint16_t> g_seq_number{0};
|
|
||||||
inline static std::map<
|
inline static std::map<
|
||||||
std::pair<std::string /*name*/, std::string /*domain*/>,
|
std::pair<std::string /*name*/, std::string /*domain*/>,
|
||||||
boost::asio::ip::tcp::iostream* /*stream*/>
|
boost::asio::ip::tcp::iostream* /*stream*/>
|
||||||
g_active_clients;
|
g_active_clients;
|
||||||
|
inline static std::atomic<uint16_t> g_seq_number{0};
|
||||||
inline static std::mutex g_mutex;
|
inline static std::mutex g_mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ bool RtspServer::update_source(uint8_t id,
|
|||||||
const std::string& sdp) {
|
const std::string& sdp) {
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
BOOST_LOG_TRIVIAL(debug) << "rtsp_server:: added source " << name;
|
BOOST_LOG_TRIVIAL(debug) << "rtsp_server:: added source " << name;
|
||||||
std::lock_guard<std::mutex> lock(mutex_);
|
std::scoped_lock<std::mutex> lock{mutex_};
|
||||||
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) {
|
||||||
@ -39,7 +39,7 @@ bool RtspServer::update_source(uint8_t id,
|
|||||||
void RtspServer::accept() {
|
void RtspServer::accept() {
|
||||||
acceptor_.async_accept(socket_, [this](boost::system::error_code ec) {
|
acceptor_.async_accept(socket_, [this](boost::system::error_code ec) {
|
||||||
if (!ec) {
|
if (!ec) {
|
||||||
std::lock_guard<std::mutex> lock(mutex_);
|
std::scoped_lock<std::mutex> lock{mutex_};
|
||||||
/* check for free sessions */
|
/* check for free sessions */
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
for (; i < sessions_.size(); i++) {
|
for (; i < sessions_.size(); i++) {
|
||||||
@ -73,8 +73,8 @@ bool RtspSession::announce(uint8_t id,
|
|||||||
* 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/") + config_->get_node_id() + " " +
|
||||||
config_->get_node_id() + " " + name);
|
name);
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
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"
|
||||||
@ -170,17 +170,18 @@ void RtspSession::build_response(const std::string& url) {
|
|||||||
send_error(400, "Bad Request");
|
send_error(400, "Bad Request");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto path = std::get<4>(res);
|
const auto& path = std::get<4>(res);
|
||||||
auto base_path =
|
auto base_path = std::string("/by-name/") + config_->get_node_id() + " ";
|
||||||
std::string("/by-name/") + config_->get_node_id() + " ";
|
|
||||||
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 */
|
||||||
id = session_manager_->get_source_id(path.substr(base_path.length()));
|
id = session_manager_->get_source_id(path.substr(base_path.length()));
|
||||||
} else if (path.rfind("/by-id/") != std::string::npos) {
|
} else if (path.rfind("/by-id/") != std::string::npos) {
|
||||||
try {
|
try {
|
||||||
id = stoi(path.substr(7));
|
id = (uint8_t)stoi(path.substr(7));
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
id = SessionManager::stream_id_max + 1;
|
||||||
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (id != (SessionManager::stream_id_max + 1)) {
|
if (id != (SessionManager::stream_id_max + 1)) {
|
||||||
|
@ -44,10 +44,7 @@ class RtspSession : public std::enable_shared_from_this<RtspSession> {
|
|||||||
tcp::socket socket)
|
tcp::socket socket)
|
||||||
: config_(config),
|
: config_(config),
|
||||||
session_manager_(session_manager),
|
session_manager_(session_manager),
|
||||||
socket_(std::move(socket)),
|
socket_(std::move(socket)) {}
|
||||||
length_{0},
|
|
||||||
cseq_{-1},
|
|
||||||
consumed_{0} {}
|
|
||||||
|
|
||||||
virtual ~RtspSession() {
|
virtual ~RtspSession() {
|
||||||
BOOST_LOG_TRIVIAL(debug) << "rtsp_server:: session end";
|
BOOST_LOG_TRIVIAL(debug) << "rtsp_server:: session end";
|
||||||
@ -87,18 +84,14 @@ class RtspServer {
|
|||||||
2};
|
2};
|
||||||
|
|
||||||
RtspServer() = delete;
|
RtspServer() = delete;
|
||||||
RtspServer(std::shared_ptr<SessionManager> session_manager,
|
explicit RtspServer(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),
|
||||||
sessions_(session_num_max),
|
|
||||||
sessions_start_point_(session_num_max),
|
|
||||||
acceptor_(io_service_,
|
acceptor_(io_service_,
|
||||||
tcp::endpoint(boost::asio::ip::address::from_string(
|
tcp::endpoint(boost::asio::ip::address::from_string(
|
||||||
config_->get_ip_addr_str()),
|
config_->get_ip_addr_str()),
|
||||||
config_->get_rtsp_port())),
|
config_->get_rtsp_port())) {}
|
||||||
socket_(io_service_) {}
|
|
||||||
|
|
||||||
bool init() {
|
bool init() {
|
||||||
accept();
|
accept();
|
||||||
/* start rtsp server on a separate thread */
|
/* start rtsp server on a separate thread */
|
||||||
@ -135,8 +128,8 @@ class RtspServer {
|
|||||||
boost::asio::io_service io_service_;
|
boost::asio::io_service io_service_;
|
||||||
std::shared_ptr<SessionManager> session_manager_;
|
std::shared_ptr<SessionManager> session_manager_;
|
||||||
std::shared_ptr<Config> config_;
|
std::shared_ptr<Config> config_;
|
||||||
std::vector<std::weak_ptr<RtspSession> > sessions_;
|
std::vector<std::weak_ptr<RtspSession> > sessions_{session_num_max};
|
||||||
std::vector<time_point<steady_clock> > sessions_start_point_;
|
std::vector<time_point<steady_clock> > sessions_start_point_{session_num_max};
|
||||||
tcp::acceptor acceptor_;
|
tcp::acceptor acceptor_;
|
||||||
tcp::socket socket_{io_service_};
|
tcp::socket socket_{io_service_};
|
||||||
std::future<void> res_;
|
std::future<void> res_;
|
||||||
|
@ -106,7 +106,7 @@ bool SAP::receive(bool& is_announce,
|
|||||||
is_announce = (buffer[0] == 0x20);
|
is_announce = (buffer[0] == 0x20);
|
||||||
memcpy(&msg_id_hash, buffer + 2, sizeof(msg_id_hash));
|
memcpy(&msg_id_hash, buffer + 2, sizeof(msg_id_hash));
|
||||||
memcpy(&addr, buffer + 4, sizeof(addr));
|
memcpy(&addr, buffer + 4, sizeof(addr));
|
||||||
for (int i = 8; buffer[i] != 0 && i < static_cast<int>(length); i++) {
|
for (int i = 8; i < static_cast<int>(length) && buffer[i] != 0; i++) {
|
||||||
buffer[i] = std::tolower(buffer[i]);
|
buffer[i] = std::tolower(buffer[i]);
|
||||||
}
|
}
|
||||||
if (!memcmp(buffer + 8, "application/sdp", 16)) {
|
if (!memcmp(buffer + 8, "application/sdp", 16)) {
|
||||||
|
@ -37,7 +37,7 @@ class SAP {
|
|||||||
constexpr static uint16_t max_length = 4096;
|
constexpr static uint16_t max_length = 4096;
|
||||||
|
|
||||||
SAP() = delete;
|
SAP() = delete;
|
||||||
SAP(const std::string& sap_mcast_addr);
|
explicit SAP(const std::string& sap_mcast_addr);
|
||||||
|
|
||||||
bool set_multicast_interface(const std::string& interface_ip);
|
bool set_multicast_interface(const std::string& interface_ip);
|
||||||
bool announcement(uint16_t msg_id_hash,
|
bool announcement(uint16_t msg_id_hash,
|
||||||
|
@ -409,7 +409,7 @@ bool SessionManager::load_status() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SessionManager::save_status() {
|
bool SessionManager::save_status() const {
|
||||||
if (config_->get_status_file().empty()) {
|
if (config_->get_status_file().empty()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -443,7 +443,8 @@ uint8_t SessionManager::get_source_id(const std::string& name) const {
|
|||||||
return it != source_names_.end() ? it->second : (stream_id_max + 1);
|
return it != source_names_.end() ? it->second : (stream_id_max + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SessionManager::add_source_observer(ObserverType type, Observer cb) {
|
void SessionManager::add_source_observer(ObserverType type,
|
||||||
|
const Observer& cb) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ObserverType::add_source:
|
case ObserverType::add_source:
|
||||||
add_source_observers.push_back(cb);
|
add_source_observers.push_back(cb);
|
||||||
@ -459,7 +460,7 @@ void SessionManager::add_source_observer(ObserverType type, Observer cb) {
|
|||||||
|
|
||||||
void SessionManager::on_add_source(const StreamSource& source,
|
void SessionManager::on_add_source(const StreamSource& source,
|
||||||
const StreamInfo& info) {
|
const StreamInfo& info) {
|
||||||
for (auto cb : add_source_observers) {
|
for (const auto& cb : add_source_observers) {
|
||||||
cb(source.id, source.name, get_source_sdp_(source.id, info));
|
cb(source.id, source.name, get_source_sdp_(source.id, info));
|
||||||
}
|
}
|
||||||
if (IN_MULTICAST(info.stream.m_ui32DestIP)) {
|
if (IN_MULTICAST(info.stream.m_ui32DestIP)) {
|
||||||
@ -470,8 +471,8 @@ void SessionManager::on_add_source(const StreamSource& source,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SessionManager::on_remove_source(const StreamInfo& info) {
|
void SessionManager::on_remove_source(const StreamInfo& info) {
|
||||||
for (auto cb : remove_source_observers) {
|
for (const auto& cb : remove_source_observers) {
|
||||||
cb(info.stream.m_uiId, info.stream.m_cName, {});
|
cb((uint8_t)info.stream.m_uiId, info.stream.m_cName, {});
|
||||||
}
|
}
|
||||||
if (IN_MULTICAST(info.stream.m_ui32DestIP)) {
|
if (IN_MULTICAST(info.stream.m_ui32DestIP)) {
|
||||||
igmp_.leave(config_->get_ip_addr_str(),
|
igmp_.leave(config_->get_ip_addr_str(),
|
||||||
@ -531,13 +532,14 @@ std::error_code SessionManager::add_source(const StreamSource& source) {
|
|||||||
config_->get_interface_name(),
|
config_->get_interface_name(),
|
||||||
ip::address_v4(info.stream.m_ui32DestIP).to_string());
|
ip::address_v4(info.stream.m_ui32DestIP).to_string());
|
||||||
int retry = 3;
|
int retry = 3;
|
||||||
while (!mac_addr.second.length() && retry--) {
|
while (!mac_addr.second.length() && retry > 0) {
|
||||||
// if not in cache already try to populate the MAC cache
|
// if not in cache already try to populate the MAC cache
|
||||||
(void)echo_try_connect(
|
(void)echo_try_connect(
|
||||||
ip::address_v4(info.stream.m_ui32DestIP).to_string());
|
ip::address_v4(info.stream.m_ui32DestIP).to_string());
|
||||||
mac_addr = get_mac_from_arp_cache(
|
mac_addr = get_mac_from_arp_cache(
|
||||||
config_->get_interface_name(),
|
config_->get_interface_name(),
|
||||||
ip::address_v4(info.stream.m_ui32DestIP).to_string());
|
ip::address_v4(info.stream.m_ui32DestIP).to_string());
|
||||||
|
retry--;
|
||||||
}
|
}
|
||||||
if (!mac_addr.second.length()) {
|
if (!mac_addr.second.length()) {
|
||||||
BOOST_LOG_TRIVIAL(error)
|
BOOST_LOG_TRIVIAL(error)
|
||||||
@ -693,8 +695,7 @@ std::error_code SessionManager::remove_source(uint32_t id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::error_code ret;
|
std::error_code ret;
|
||||||
const auto& info = (*it).second;
|
if (const auto& info = (*it).second; info.enabled) {
|
||||||
if (info.enabled) {
|
|
||||||
ret = driver_->remove_rtp_stream(info.handle);
|
ret = driver_->remove_rtp_stream(info.handle);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
on_remove_source(info);
|
on_remove_source(info);
|
||||||
@ -808,7 +809,7 @@ std::error_code SessionManager::add_sink(const StreamSink& sink) {
|
|||||||
return DaemonErrc::cannot_parse_sdp;
|
return DaemonErrc::cannot_parse_sdp;
|
||||||
}
|
}
|
||||||
|
|
||||||
info.sink_sdp = std::move(sink.sdp);
|
info.sink_sdp = sink.sdp;
|
||||||
}
|
}
|
||||||
info.sink_source = sink.source;
|
info.sink_source = sink.source;
|
||||||
info.sink_use_sdp = true; // save back and use with SDP file
|
info.sink_use_sdp = true; // save back and use with SDP file
|
||||||
@ -1076,7 +1077,7 @@ void SessionManager::on_update_sources() {
|
|||||||
// trigger sources SDP file update
|
// trigger sources SDP file update
|
||||||
sources_mutex_.lock();
|
sources_mutex_.lock();
|
||||||
for (auto& [id, info] : sources_) {
|
for (auto& [id, info] : sources_) {
|
||||||
for (auto cb : update_source_observers) {
|
for (const auto& cb : update_source_observers) {
|
||||||
info.session_version++;
|
info.session_version++;
|
||||||
cb(id, info.stream.m_cName, get_source_sdp_(id, info));
|
cb(id, info.stream.m_cName, get_source_sdp_(id, info));
|
||||||
}
|
}
|
||||||
@ -1102,9 +1103,8 @@ void SessionManager::on_ptp_status_changed(const std::string& status) const {
|
|||||||
for (int i = STDERR_FILENO + 1; i < fdlimit; i++)
|
for (int i = STDERR_FILENO + 1; i < fdlimit; i++)
|
||||||
close(i);
|
close(i);
|
||||||
|
|
||||||
char* argv_list[] = {
|
char* argv_list[] = {(char*)(config_->get_ptp_status_script().c_str()),
|
||||||
const_cast<char*>(config_->get_ptp_status_script().c_str()),
|
(char*)(status.c_str()), nullptr};
|
||||||
const_cast<char*>(status.c_str()), NULL};
|
|
||||||
|
|
||||||
execv(config_->get_ptp_status_script().c_str(), argv_list);
|
execv(config_->get_ptp_status_script().c_str(), argv_list);
|
||||||
exit(0);
|
exit(0);
|
||||||
|
@ -86,7 +86,7 @@ struct PTPStatus {
|
|||||||
struct StreamInfo {
|
struct StreamInfo {
|
||||||
TRTP_stream_info stream;
|
TRTP_stream_info stream;
|
||||||
uint64_t handle{0};
|
uint64_t handle{0};
|
||||||
bool enabled{0};
|
bool enabled{false};
|
||||||
bool refclk_ptp_traceable{false};
|
bool refclk_ptp_traceable{false};
|
||||||
bool ignore_refclk_gmid{false};
|
bool ignore_refclk_gmid{false};
|
||||||
std::string io;
|
std::string io;
|
||||||
@ -109,7 +109,7 @@ class SessionManager {
|
|||||||
SessionManager() = delete;
|
SessionManager() = delete;
|
||||||
SessionManager(const SessionManager&) = delete;
|
SessionManager(const SessionManager&) = delete;
|
||||||
SessionManager& operator=(const SessionManager&) = delete;
|
SessionManager& operator=(const SessionManager&) = delete;
|
||||||
virtual ~SessionManager() { terminate(); };
|
virtual ~SessionManager() = default;
|
||||||
|
|
||||||
// session manager interface
|
// session manager interface
|
||||||
bool init() {
|
bool init() {
|
||||||
@ -127,10 +127,10 @@ class SessionManager {
|
|||||||
if (running_) {
|
if (running_) {
|
||||||
running_ = false;
|
running_ = false;
|
||||||
auto ret = res_.get();
|
auto ret = res_.get();
|
||||||
for (auto source : get_sources()) {
|
for (const auto& source : get_sources()) {
|
||||||
remove_source(source.id);
|
remove_source(source.id);
|
||||||
}
|
}
|
||||||
for (auto sink : get_sinks()) {
|
for (const auto& sink : get_sinks()) {
|
||||||
remove_sink(sink.id);
|
remove_sink(sink.id);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -148,7 +148,7 @@ class SessionManager {
|
|||||||
enum class ObserverType { add_source, remove_source, update_source };
|
enum class ObserverType { add_source, remove_source, update_source };
|
||||||
using Observer = std::function<
|
using Observer = std::function<
|
||||||
bool(uint8_t id, const std::string& name, 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, const Observer& cb);
|
||||||
|
|
||||||
std::error_code add_sink(const StreamSink& sink);
|
std::error_code add_sink(const StreamSink& sink);
|
||||||
std::error_code get_sink(uint8_t id, StreamSink& sink) const;
|
std::error_code get_sink(uint8_t id, StreamSink& sink) const;
|
||||||
@ -164,7 +164,7 @@ class SessionManager {
|
|||||||
void get_ptp_status(PTPStatus& status) const;
|
void get_ptp_status(PTPStatus& status) const;
|
||||||
|
|
||||||
bool load_status();
|
bool load_status();
|
||||||
bool save_status();
|
bool save_status() const;
|
||||||
|
|
||||||
size_t process_sap();
|
size_t process_sap();
|
||||||
|
|
||||||
@ -200,14 +200,15 @@ class SessionManager {
|
|||||||
bool parse_sdp(const std::string sdp, StreamInfo& info) const;
|
bool parse_sdp(const std::string sdp, StreamInfo& info) const;
|
||||||
bool worker();
|
bool worker();
|
||||||
// singleton, use create() to build
|
// singleton, use create() to build
|
||||||
SessionManager(std::shared_ptr<DriverManager> driver,
|
explicit SessionManager(std::shared_ptr<DriverManager> driver,
|
||||||
std::shared_ptr<Browser> browser,
|
std::shared_ptr<Browser> browser,
|
||||||
std::shared_ptr<Config> config)
|
std::shared_ptr<Config> config)
|
||||||
: browser_(browser), driver_(driver), config_(config) {
|
: browser_(browser), driver_(driver), config_(config) {
|
||||||
ptp_config_.domain = config->get_ptp_domain();
|
ptp_config_.domain = config->get_ptp_domain();
|
||||||
ptp_config_.dscp = config->get_ptp_dscp();
|
ptp_config_.dscp = config->get_ptp_dscp();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
std::shared_ptr<Browser> browser_;
|
std::shared_ptr<Browser> browser_;
|
||||||
std::shared_ptr<DriverManager> driver_;
|
std::shared_ptr<DriverManager> driver_;
|
||||||
std::shared_ptr<Config> config_;
|
std::shared_ptr<Config> config_;
|
||||||
|
@ -70,7 +70,8 @@ struct DaemonInstance {
|
|||||||
auto pid = daemon_.native_handle();
|
auto pid = daemon_.native_handle();
|
||||||
/* trigger normal daemon termination */
|
/* trigger normal daemon termination */
|
||||||
kill(pid, SIGTERM);
|
kill(pid, SIGTERM);
|
||||||
daemon_.wait();
|
std::error_code ec;
|
||||||
|
daemon_.wait(ec);
|
||||||
BOOST_REQUIRE_MESSAGE(!daemon_.exit_code(), "daemon exited normally");
|
BOOST_REQUIRE_MESSAGE(!daemon_.exit_code(), "daemon exited normally");
|
||||||
ok = false;
|
ok = false;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user