Enhancement of daemon reconfiguration and PTP status update notification via shell script. See #82
The daemon can apply a configuration change to the following parameters without a restart: sap_interval, syslog_proto, syslog_server, log_severity, sample_rate The daemon can apply a configuration change to the following parameters without a light restart: http_port, rtsp_port, http_base_dir, rtp_mcast_base, sap_mcast_addr, rtp_port, rtp_port, status_file, interface_name, mdns_enabled A light restart means that the configuration can be applied without interrupting the playback/capture applications A change to one of following paramters causes a full daemon restart: interface_name, tic_frame_size_at_1fs, max_tic_frame_size On PTP status change the daemon can run in background an external shell script whose path name is specified by the new ptp_status_script Config parameter. If this parameter is empty, no script is invoked. The PTP clock status is passed as first parameter to the script and it can be unlocked, locking or locked. A sample script is provided in daemon/scripts/ptp_status.sh
This commit is contained in:
parent
cde35a7b7c
commit
dbb593120a
@ -185,7 +185,8 @@ Example
|
||||
"sap_interval": 30,
|
||||
"mac_addr": "01:00:5e:01:00:01",
|
||||
"ip_addr": "127.0.0.1",
|
||||
"node_id": "AES67 daemon ubuntu-d9aca383"
|
||||
"node_id": "AES67 daemon ubuntu-d9aca383",
|
||||
"ptp_status_script": "./scripts/ptp_status.sh"
|
||||
}
|
||||
|
||||
where:
|
||||
@ -221,7 +222,7 @@ where:
|
||||
> The specific multicast RTP address is the base address plus the source id number.
|
||||
> For example if the base address is 239.2.0.1 and source id is 1 the RTP source address used is 239.2.0.2.
|
||||
|
||||
> **rtp_port**
|
||||
> **rtp\_port**
|
||||
> JSON number specifying the RTP port used by the sources.
|
||||
|
||||
> **ptp\_domain**
|
||||
@ -267,6 +268,10 @@ where:
|
||||
> JSON string specifying the unique node identifier used to identify mDNS, SAP and SDP services announced by the daemon.
|
||||
> **_NOTE:_** This parameter is read-only and cannot be set. The server will determine the node id at startup time.
|
||||
|
||||
> **ptp\_status\_script**
|
||||
> JSON string specifying the path to the script executed in background when the PTP slave clock status changes.
|
||||
> The PTP clock status is passed as first parameter to the script and it can be *unlocked*, *locking* or *locked*.
|
||||
|
||||
### JSON PTP Config<a name="ptp-config"></a> ###
|
||||
|
||||
Example
|
||||
|
@ -101,9 +101,9 @@ bool Browser::worker() {
|
||||
duration_cast<second_t>(steady_clock::now() - startup_).count();
|
||||
auto upd_source{*it};
|
||||
if ((last_seen - upd_source.last_seen) != 0) {
|
||||
upd_source.announce_period = last_seen - upd_source.last_seen;
|
||||
upd_source.last_seen = last_seen;
|
||||
sources_.replace(it, upd_source);
|
||||
upd_source.announce_period = last_seen - upd_source.last_seen;
|
||||
upd_source.last_seen = last_seen;
|
||||
sources_.replace(it, upd_source);
|
||||
}
|
||||
} else {
|
||||
BOOST_LOG_TRIVIAL(info) << "browser:: removing SAP source " << it->id
|
||||
|
@ -36,7 +36,8 @@
|
||||
|
||||
using namespace boost::asio;
|
||||
|
||||
std::shared_ptr<Config> Config::parse(const std::string& filename) {
|
||||
std::shared_ptr<Config> Config::parse(const std::string& filename,
|
||||
bool driver_restart) {
|
||||
Config config;
|
||||
|
||||
std::ifstream jsonstream(filename);
|
||||
@ -104,20 +105,43 @@ std::shared_ptr<Config> Config::parse(const std::string& filename) {
|
||||
}
|
||||
|
||||
config.config_filename_ = filename;
|
||||
config.need_restart_ = false;
|
||||
config.daemon_restart_ = false;
|
||||
config.driver_restart_ = driver_restart;
|
||||
|
||||
return std::make_shared<Config>(config);
|
||||
}
|
||||
|
||||
bool Config::save(const Config& config, bool need_restart) {
|
||||
std::ofstream js(config_filename_);
|
||||
if (!js) {
|
||||
BOOST_LOG_TRIVIAL(fatal)
|
||||
<< "Config:: cannot save to file " << config_filename_;
|
||||
return false;
|
||||
bool Config::save(const Config& config) {
|
||||
if (*this != config) {
|
||||
std::ofstream js(config_filename_);
|
||||
if (!js) {
|
||||
BOOST_LOG_TRIVIAL(fatal)
|
||||
<< "Config:: cannot save to file " << config_filename_;
|
||||
return false;
|
||||
}
|
||||
js << config_to_json(config);
|
||||
|
||||
driver_restart_ =
|
||||
get_tic_frame_size_at_1fs() != config.get_tic_frame_size_at_1fs() ||
|
||||
get_max_tic_frame_size() != config.get_max_tic_frame_size() ||
|
||||
get_interface_name() != config.get_interface_name();
|
||||
|
||||
daemon_restart_ = driver_restart_ ||
|
||||
get_http_port() != config.get_http_port() ||
|
||||
get_rtsp_port() != config.get_rtsp_port() ||
|
||||
get_http_base_dir() != config.get_http_base_dir() ||
|
||||
get_rtp_mcast_base() != config.get_rtp_mcast_base() ||
|
||||
get_sap_mcast_addr() != config.get_sap_mcast_addr() ||
|
||||
get_rtp_port() != config.get_rtp_port() ||
|
||||
get_status_file() != config.get_status_file() ||
|
||||
get_mdns_enabled() != config.get_mdns_enabled();
|
||||
|
||||
if (!daemon_restart_)
|
||||
*this = config;
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << "Config:: file saved";
|
||||
} else {
|
||||
BOOST_LOG_TRIVIAL(info) << "Config:: unchanged";
|
||||
}
|
||||
js << config_to_json(config);
|
||||
BOOST_LOG_TRIVIAL(info) << "Config:: file saved";
|
||||
need_restart_ = need_restart;
|
||||
return true;
|
||||
}
|
||||
|
@ -27,9 +27,10 @@
|
||||
class Config {
|
||||
public:
|
||||
/* save new config to json file */
|
||||
bool save(const Config& config, bool need_restart = true);
|
||||
bool save(const Config& config);
|
||||
/* build config from json file */
|
||||
static std::shared_ptr<Config> parse(const std::string& filename);
|
||||
static std::shared_ptr<Config> parse(const std::string& filename,
|
||||
bool driver_restart);
|
||||
|
||||
/* attributes retrieved from config json */
|
||||
uint16_t get_http_port() const { return http_port_; };
|
||||
@ -57,9 +58,13 @@ class Config {
|
||||
const std::string& get_mac_addr_str() const { return mac_str_; };
|
||||
uint32_t get_ip_addr() const { return ip_addr_; };
|
||||
const std::string& get_ip_addr_str() const { return ip_str_; };
|
||||
bool get_need_restart() const { return need_restart_; };
|
||||
bool get_daemon_restart() const { return daemon_restart_; };
|
||||
bool get_driver_restart() const { return driver_restart_; };
|
||||
bool get_mdns_enabled() const { return mdns_enabled_; };
|
||||
int get_interface_idx() { return interface_idx_; };
|
||||
const std::string& get_ptp_status_script() const {
|
||||
return ptp_status_script_;
|
||||
}
|
||||
|
||||
void set_http_port(uint16_t http_port) { http_port_ = http_port; };
|
||||
void set_rtsp_port(uint16_t rtsp_port) { rtsp_port_ = rtsp_port; };
|
||||
@ -109,6 +114,35 @@ class Config {
|
||||
};
|
||||
void set_mdns_enabled(bool enabled) { mdns_enabled_ = enabled; };
|
||||
void set_interface_idx(int index) { interface_idx_ = index; };
|
||||
void set_ptp_status_script(const std::string& script) {
|
||||
ptp_status_script_ = script;
|
||||
};
|
||||
void set_driver_restart(bool restart) { driver_restart_ = restart; }
|
||||
|
||||
friend bool operator!=(const Config& lhs, const Config& rhs) {
|
||||
return lhs.get_http_port() != rhs.get_http_port() ||
|
||||
lhs.get_rtsp_port() != rhs.get_rtsp_port() ||
|
||||
lhs.get_http_base_dir() != rhs.get_http_base_dir() ||
|
||||
lhs.get_log_severity() != rhs.get_log_severity() ||
|
||||
lhs.get_playout_delay() != rhs.get_playout_delay() ||
|
||||
lhs.get_tic_frame_size_at_1fs() != rhs.get_tic_frame_size_at_1fs() ||
|
||||
lhs.get_max_tic_frame_size() != rhs.get_max_tic_frame_size() ||
|
||||
lhs.get_sample_rate() != rhs.get_sample_rate() ||
|
||||
lhs.get_rtp_mcast_base() != rhs.get_rtp_mcast_base() ||
|
||||
lhs.get_sap_mcast_addr() != rhs.get_sap_mcast_addr() ||
|
||||
lhs.get_rtp_port() != rhs.get_rtp_port() ||
|
||||
lhs.get_ptp_domain() != rhs.get_ptp_domain() ||
|
||||
lhs.get_ptp_dscp() != rhs.get_ptp_dscp() ||
|
||||
lhs.get_sap_interval() != rhs.get_sap_interval() ||
|
||||
lhs.get_syslog_proto() != rhs.get_syslog_proto() ||
|
||||
lhs.get_syslog_server() != rhs.get_syslog_server() ||
|
||||
lhs.get_status_file() != rhs.get_status_file() ||
|
||||
lhs.get_interface_name() != rhs.get_interface_name() ||
|
||||
lhs.get_mdns_enabled() != rhs.get_mdns_enabled();
|
||||
};
|
||||
friend bool operator==(const Config& lhs, const Config& rhs) {
|
||||
return !(lhs != rhs);
|
||||
};
|
||||
|
||||
private:
|
||||
/* from json */
|
||||
@ -131,6 +165,7 @@ class Config {
|
||||
std::string status_file_{"./status.json"};
|
||||
std::string interface_name_{"eth0"};
|
||||
bool mdns_enabled_{true};
|
||||
std::string ptp_status_script_;
|
||||
|
||||
/* set during init */
|
||||
std::array<uint8_t, 6> mac_addr_{0, 0, 0, 0, 0, 0};
|
||||
@ -140,8 +175,10 @@ class Config {
|
||||
int interface_idx_;
|
||||
std::string config_filename_;
|
||||
|
||||
/* reconfig needs driver restart */
|
||||
bool driver_restart_{true};
|
||||
/* reconfig needs daemon restart */
|
||||
bool need_restart_{false};
|
||||
bool daemon_restart_{false};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -16,6 +16,7 @@
|
||||
"syslog_proto": "none",
|
||||
"syslog_server": "255.255.255.254:1234",
|
||||
"status_file": "./status.json",
|
||||
"interface_name": "lo",
|
||||
"mdns_enabled": true,
|
||||
"interface_name": "lo"
|
||||
"ptp_status_script": "./scripts/ptp_status.sh"
|
||||
}
|
||||
|
@ -130,7 +130,7 @@ bool DriverHandler::event_receiver() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DriverHandler::terminate() {
|
||||
bool DriverHandler::terminate(const Config& /* config */) {
|
||||
if (running_) {
|
||||
running_ = false;
|
||||
client_u2k_.terminate();
|
||||
|
@ -40,10 +40,10 @@ class DriverHandler {
|
||||
DriverHandler(){};
|
||||
DriverHandler(const DriverHandler&) = delete;
|
||||
DriverHandler& operator=(const DriverHandler&) = delete;
|
||||
virtual ~DriverHandler() { terminate(); };
|
||||
virtual ~DriverHandler(){};
|
||||
|
||||
virtual bool init(const Config& config);
|
||||
virtual bool terminate();
|
||||
virtual bool terminate(const Config& config);
|
||||
|
||||
protected:
|
||||
virtual void send_command(enum MT_ALSA_msg_id id,
|
||||
|
@ -81,20 +81,28 @@ bool DriverManager::init(const Config& config) {
|
||||
ptp_config.ui8Domain = config.get_ptp_domain();
|
||||
ptp_config.ui8DSCP = config.get_ptp_dscp();
|
||||
|
||||
bool res = hello() || start() || reset() ||
|
||||
set_interface_name(config.get_interface_name()) ||
|
||||
set_ptp_config(ptp_config) ||
|
||||
set_tic_frame_size_at_1fs(config.get_tic_frame_size_at_1fs()) ||
|
||||
set_playout_delay(config.get_playout_delay()) ||
|
||||
set_max_tic_frame_size(config.get_max_tic_frame_size());
|
||||
if (hello())
|
||||
return false;
|
||||
|
||||
bool res(false);
|
||||
if (config.get_driver_restart()) {
|
||||
res = start() || reset() ||
|
||||
set_interface_name(config.get_interface_name()) ||
|
||||
set_ptp_config(ptp_config) ||
|
||||
set_tic_frame_size_at_1fs(config.get_tic_frame_size_at_1fs()) ||
|
||||
set_playout_delay(config.get_playout_delay()) ||
|
||||
set_max_tic_frame_size(config.get_max_tic_frame_size());
|
||||
}
|
||||
|
||||
return !res;
|
||||
}
|
||||
|
||||
bool DriverManager::terminate() {
|
||||
stop();
|
||||
bool DriverManager::terminate(const Config& config) {
|
||||
if (config.get_driver_restart()) {
|
||||
stop();
|
||||
}
|
||||
bye();
|
||||
return DriverHandler::terminate();
|
||||
return DriverHandler::terminate(config);
|
||||
}
|
||||
|
||||
std::error_code DriverManager::hello() {
|
||||
|
@ -33,7 +33,7 @@ class DriverManager : public DriverHandler {
|
||||
|
||||
// driver interface
|
||||
bool init(const Config& config) override;
|
||||
bool terminate() override;
|
||||
bool terminate(const Config& config) override;
|
||||
|
||||
std::error_code ping(); // unused, return error
|
||||
std::error_code set_ptp_config(const TPTPConfig& config);
|
||||
|
@ -115,6 +115,30 @@ bool HttpServer::init() {
|
||||
svr_.Post("/api/config", [this](const Request& req, Response& res) {
|
||||
try {
|
||||
Config config = json_to_config(req.body, *config_);
|
||||
|
||||
if (config_->get_syslog_proto() != config.get_syslog_proto() ||
|
||||
config_->get_syslog_server() != config.get_syslog_server() ||
|
||||
config_->get_log_severity() != config.get_log_severity()) {
|
||||
log_init(config);
|
||||
}
|
||||
std::error_code ret;
|
||||
if (config_->get_playout_delay() != config.get_playout_delay()) {
|
||||
ret = session_manager_->set_driver_config("playout_delay",
|
||||
config.get_playout_delay());
|
||||
}
|
||||
if (config_->get_sample_rate() != config.get_sample_rate()) {
|
||||
ret = session_manager_->set_driver_config("sample_rate",
|
||||
config.get_sample_rate());
|
||||
}
|
||||
if (config_->get_ptp_domain() != config.get_ptp_domain() ||
|
||||
config_->get_ptp_dscp() != config.get_ptp_dscp()) {
|
||||
PTPConfig ptpConfig{config.get_ptp_domain(), config.get_ptp_dscp()};
|
||||
ret = session_manager_->set_ptp_config(ptpConfig);
|
||||
}
|
||||
if (ret) {
|
||||
set_error(ret, "failed to set config", res);
|
||||
return;
|
||||
}
|
||||
if (!config_->save(config)) {
|
||||
set_error(500, "failed to save config", res);
|
||||
return;
|
||||
@ -153,7 +177,7 @@ bool HttpServer::init() {
|
||||
Config config(*config_);
|
||||
config.set_ptp_domain(ptpConfig.domain);
|
||||
config.set_ptp_dscp(ptpConfig.dscp);
|
||||
if (!config_->save(config, false)) {
|
||||
if (!config_->save(config)) {
|
||||
set_error(500, "failed to save config", res);
|
||||
return;
|
||||
}
|
||||
|
@ -115,7 +115,6 @@ int get_interface_index(const std::string& interface_name) {
|
||||
return ifr.ifr_ifindex;
|
||||
}
|
||||
|
||||
|
||||
std::pair<std::array<uint8_t, 6>, std::string> get_mac_from_arp_cache(
|
||||
const std::string& interface_name,
|
||||
const std::string& ip) {
|
||||
@ -155,7 +154,6 @@ std::pair<std::array<uint8_t, 6>, std::string> get_mac_from_arp_cache(
|
||||
return {mac, ""};
|
||||
}
|
||||
|
||||
|
||||
bool ping(const std::string& ip) {
|
||||
static uint16_t sequence_number(0);
|
||||
uint16_t identifier(0xABAB);
|
||||
@ -182,7 +180,6 @@ bool ping(const std::string& ip) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool echo_try_connect(const std::string& ip) {
|
||||
ip::tcp::iostream s;
|
||||
BOOST_LOG_TRIVIAL(debug) << "echo_connect:: connecting to " << ip;
|
||||
|
@ -104,6 +104,8 @@ std::string config_to_json(const Config& config) {
|
||||
<< ",\n \"ip_addr\": \"" << escape_json(config.get_ip_addr_str()) << "\""
|
||||
<< ",\n \"node_id\": \"" << escape_json(get_node_id(config.get_ip_addr()))
|
||||
<< "\""
|
||||
<< ",\n \"ptp_status_script\": \""
|
||||
<< escape_json(config.get_ptp_status_script()) << "\""
|
||||
<< "\n}\n";
|
||||
return ss.str();
|
||||
}
|
||||
@ -158,8 +160,8 @@ std::string sink_to_json(const StreamSink& sink) {
|
||||
std::string sink_status_to_json(const SinkStreamStatus& status) {
|
||||
std::stringstream ss;
|
||||
ss << "{";
|
||||
ss << " \n \"sink_flags\":\n {" << std::boolalpha
|
||||
<< " \n \"rtp_seq_id_error\": " << status.is_rtp_seq_id_error
|
||||
ss << "\n \"sink_flags\":\n {" << std::boolalpha
|
||||
<< " \n \"rtp_seq_id_error\": " << status.is_rtp_seq_id_error
|
||||
<< ", \n \"rtp_ssrc_error\": " << status.is_rtp_ssrc_error
|
||||
<< ", \n \"rtp_payload_type_error\": "
|
||||
<< status.is_rtp_payload_type_error
|
||||
@ -320,6 +322,9 @@ Config json_to_config_(std::istream& js, Config& config) {
|
||||
} else if (key == "syslog_server") {
|
||||
config.set_syslog_server(
|
||||
remove_undesired_chars(val.get_value<std::string>()));
|
||||
} else if (key == "ptp_status_script") {
|
||||
config.set_ptp_status_script(
|
||||
remove_undesired_chars(val.get_value<std::string>()));
|
||||
} else if (key == "mac_addr" || key == "ip_addr" || key == "node_id") {
|
||||
/* ignored */
|
||||
} else {
|
||||
|
@ -35,7 +35,7 @@ namespace po = boost::program_options;
|
||||
namespace postyle = boost::program_options::command_line_style;
|
||||
namespace logging = boost::log;
|
||||
|
||||
static std::string version("bondagit-1.4");
|
||||
static std::string version("bondagit-1.5");
|
||||
static std::atomic<bool> terminate = false;
|
||||
|
||||
void termination_handler(int signum) {
|
||||
@ -53,15 +53,16 @@ const std::string& get_version() {
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
int rc = EXIT_SUCCESS;
|
||||
int rc(EXIT_SUCCESS);
|
||||
po::options_description desc("Options");
|
||||
desc.add_options()
|
||||
("version,v", "Print daemon version and exit")
|
||||
("config,c", po::value<std::string>()->default_value("/etc/daemon.conf"),
|
||||
"daemon configuration file")
|
||||
("http_port,p", po::value<int>(), "HTTP server port")
|
||||
("help,h", "Print this help message");
|
||||
desc.add_options()("version,v", "Print daemon version and exit")(
|
||||
"config,c", po::value<std::string>()->default_value("/etc/daemon.conf"),
|
||||
"daemon configuration file")("http_port,p", po::value<int>(),
|
||||
"HTTP server port")("help,h",
|
||||
"Print this help "
|
||||
"message");
|
||||
int unix_style = postyle::unix_style | postyle::short_allow_next;
|
||||
bool driver_restart(true);
|
||||
|
||||
po::variables_map vm;
|
||||
try {
|
||||
@ -98,7 +99,7 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
while (!is_terminated() && rc == EXIT_SUCCESS) {
|
||||
/* load configuration from file */
|
||||
auto config = Config::parse(filename);
|
||||
auto config = Config::parse(filename, driver_restart);
|
||||
if (config == nullptr) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
@ -165,7 +166,8 @@ int main(int argc, char* argv[]) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (config->get_need_restart()) {
|
||||
driver_restart = config->get_driver_restart();
|
||||
if (config->get_daemon_restart()) {
|
||||
BOOST_LOG_TRIVIAL(warning) << "main:: config changed, restarting ...";
|
||||
break;
|
||||
}
|
||||
@ -205,7 +207,7 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
|
||||
/* stop driver manager */
|
||||
if (!driver->terminate()) {
|
||||
if (!driver->terminate(*config)) {
|
||||
throw std::runtime_error(
|
||||
std::string("DriverManager:: terminate failed"));
|
||||
}
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include "rtsp_client.hpp"
|
||||
#include "mdns_client.hpp"
|
||||
|
||||
|
||||
#ifdef _USE_AVAHI_
|
||||
void MDNSClient::resolve_callback(AvahiServiceResolver* r,
|
||||
AvahiIfIndex interface,
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include "utils.hpp"
|
||||
#include "mdns_server.hpp"
|
||||
|
||||
|
||||
#ifdef _USE_AVAHI_
|
||||
struct AvahiLockGuard {
|
||||
AvahiLockGuard() = delete;
|
||||
|
@ -15,7 +15,6 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
#include "utils.hpp"
|
||||
#include "rtsp_server.hpp"
|
||||
|
||||
|
11
daemon/scripts/ptp_status.sh
Executable file
11
daemon/scripts/ptp_status.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ $1 == "locked" ]; then
|
||||
echo "$0 >> PTP locked";
|
||||
#speaker-test -D plughw:RAVENNA -r 48000 -c 2 -t sine &
|
||||
elif [ $1 == "locking" ]; then
|
||||
echo "$0 >> PTP locking";
|
||||
elif [ $1 == "unlocked" ]; then
|
||||
echo "$0 >> PTP unlocked";
|
||||
#killall -9 speaker-test
|
||||
fi
|
@ -19,6 +19,7 @@
|
||||
|
||||
#define CPPHTTPLIB_PAYLOAD_MAX_LENGTH 4096 // max for SDP file
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <httplib.h>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
@ -479,7 +480,7 @@ std::error_code SessionManager::add_source(const StreamSource& source) {
|
||||
info.stream.m_ui32CRTP_stream_info_sizeof = sizeof(info.stream);
|
||||
strncpy(info.stream.m_cName, source.name.c_str(),
|
||||
sizeof(info.stream.m_cName) - 1);
|
||||
info.stream.m_ucDSCP = source.dscp; // IPv4 DSCP
|
||||
info.stream.m_ucDSCP = source.dscp; // IPv4 DSCP
|
||||
info.stream.m_byPayloadType = source.payload_type;
|
||||
info.stream.m_byWordLength = get_codec_word_lenght(source.codec);
|
||||
info.stream.m_byNbOfChannels = source.map.size();
|
||||
@ -513,13 +514,16 @@ std::error_code SessionManager::add_source(const StreamSource& source) {
|
||||
info.stream.m_ui8DestMAC);
|
||||
info.stream.m_byTTL = source.ttl;
|
||||
} else {
|
||||
auto mac_addr = get_mac_from_arp_cache(config_->get_interface_name(),
|
||||
auto mac_addr = get_mac_from_arp_cache(
|
||||
config_->get_interface_name(),
|
||||
ip::address_v4(info.stream.m_ui32DestIP).to_string());
|
||||
int retry = 3;
|
||||
while (!mac_addr.second.length() && retry--) {
|
||||
// if not in cache already try to populate the MAC cache
|
||||
(void)echo_try_connect(ip::address_v4(info.stream.m_ui32DestIP).to_string());
|
||||
mac_addr = get_mac_from_arp_cache(config_->get_interface_name(),
|
||||
(void)echo_try_connect(
|
||||
ip::address_v4(info.stream.m_ui32DestIP).to_string());
|
||||
mac_addr = get_mac_from_arp_cache(
|
||||
config_->get_interface_name(),
|
||||
ip::address_v4(info.stream.m_ui32DestIP).to_string());
|
||||
}
|
||||
if (!mac_addr.second.length()) {
|
||||
@ -625,8 +629,8 @@ std::string SessionManager::get_source_sdp_(uint32_t id,
|
||||
if (IN_MULTICAST(info.stream.m_ui32DestIP)) {
|
||||
ss << "/" << static_cast<unsigned>(info.stream.m_byTTL);
|
||||
}
|
||||
ss << "\na=rtpmap:" << static_cast<unsigned>(info.stream.m_byPayloadType) << " "
|
||||
<< info.stream.m_cCodec << "/" << sample_rate << "/"
|
||||
ss << "\na=rtpmap:" << static_cast<unsigned>(info.stream.m_byPayloadType)
|
||||
<< " " << info.stream.m_cCodec << "/" << sample_rate << "/"
|
||||
<< static_cast<unsigned>(info.stream.m_byNbOfChannels) << "\n"
|
||||
<< "a=sync-time:0\n"
|
||||
<< "a=framecount:" << info.stream.m_ui32MaxSamplesPerPacket << "\n"
|
||||
@ -902,6 +906,19 @@ std::error_code SessionManager::get_sink_status(
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::error_code SessionManager::set_driver_config(const std::string& name,
|
||||
uint32_t value) const {
|
||||
if (name == "sample_rate")
|
||||
return driver_->set_sample_rate(value);
|
||||
else if (name == "tic_frame_size_at_1fs")
|
||||
return driver_->set_tic_frame_size_at_1fs(value);
|
||||
else if (name == "set_max_tic_frame_size")
|
||||
return driver_->set_max_tic_frame_size(value);
|
||||
else if (name == "playout_delay")
|
||||
return driver_->set_playout_delay(value);
|
||||
return DriverErrc::unknown;
|
||||
}
|
||||
|
||||
std::error_code SessionManager::set_ptp_config(const PTPConfig& config) {
|
||||
TPTPConfig ptp_config;
|
||||
ptp_config.ui8Domain = config.domain;
|
||||
@ -1002,9 +1019,31 @@ void SessionManager::on_update_sources() {
|
||||
g_session_version++;
|
||||
}
|
||||
|
||||
void SessionManager::on_ptp_status_locked() const {
|
||||
// set sample rate, this may require seconds
|
||||
(void)driver_->set_sample_rate(driver_->get_current_sample_rate());
|
||||
void SessionManager::on_ptp_status_changed(const std::string& status) const {
|
||||
if (status == "locked") {
|
||||
// set sample rate, this may require seconds
|
||||
(void)driver_->set_sample_rate(driver_->get_current_sample_rate());
|
||||
}
|
||||
|
||||
static std::string g_ptp_status;
|
||||
|
||||
if (g_ptp_status != status && !config_->get_ptp_status_script().empty()) {
|
||||
pid_t pid = fork();
|
||||
if (pid == 0) {
|
||||
/* child */
|
||||
int fdlimit = (int)sysconf(_SC_OPEN_MAX);
|
||||
/* close all partent's fds */
|
||||
for (int i = STDERR_FILENO + 1; i < fdlimit; i++)
|
||||
close(i);
|
||||
|
||||
char* argv_list[] = {const_cast<char*>(config_->get_ptp_status_script().c_str()),
|
||||
const_cast<char*>(status.c_str()), NULL};
|
||||
|
||||
execv(config_->get_ptp_status_script().c_str(), argv_list);
|
||||
exit(0);
|
||||
}
|
||||
g_ptp_status = status;
|
||||
}
|
||||
}
|
||||
|
||||
using namespace std::chrono;
|
||||
@ -1043,7 +1082,7 @@ bool SessionManager::worker() {
|
||||
pui64GMID[5], pui64GMID[6], pui64GMID[7]);
|
||||
|
||||
bool ptp_changed_gmid = false;
|
||||
bool ptp_changed_to_locked = false;
|
||||
std::string ptp_status_changed_to;
|
||||
// update PTP clock status
|
||||
ptp_mutex_.lock();
|
||||
// update status
|
||||
@ -1069,15 +1108,13 @@ bool SessionManager::worker() {
|
||||
BOOST_LOG_TRIVIAL(info)
|
||||
<< "session_manager:: new PTP clock status " << new_ptp_status;
|
||||
ptp_status_.status = new_ptp_status;
|
||||
if (new_ptp_status == "locked") {
|
||||
ptp_changed_to_locked = true;
|
||||
}
|
||||
ptp_status_changed_to = new_ptp_status;
|
||||
}
|
||||
// end update PTP clock status
|
||||
ptp_mutex_.unlock();
|
||||
|
||||
if (ptp_changed_to_locked) {
|
||||
on_ptp_status_locked();
|
||||
if (!ptp_status_changed_to.empty()) {
|
||||
on_ptp_status_changed(ptp_status_changed_to);
|
||||
}
|
||||
|
||||
if (ptp_changed_gmid ||
|
||||
@ -1085,10 +1122,10 @@ bool SessionManager::worker() {
|
||||
/* master clock id changed or sample rate changed
|
||||
* we need to update all the sources */
|
||||
if (sample_rate != driver_->get_current_sample_rate()) {
|
||||
sample_rate = driver_->get_current_sample_rate();
|
||||
// set driver sample rate
|
||||
(void)driver_->set_sample_rate(sample_rate);
|
||||
}
|
||||
sample_rate = driver_->get_current_sample_rate();
|
||||
// set driver sample rate
|
||||
(void)driver_->set_sample_rate(sample_rate);
|
||||
}
|
||||
on_update_sources();
|
||||
}
|
||||
}
|
||||
|
@ -151,6 +151,8 @@ class SessionManager {
|
||||
uint8_t get_sink_id(const std::string& name) const;
|
||||
|
||||
std::error_code set_ptp_config(const PTPConfig& config);
|
||||
std::error_code set_driver_config(const std::string& name,
|
||||
uint32_t value) const;
|
||||
void get_ptp_config(PTPConfig& config) const;
|
||||
void get_ptp_status(PTPStatus& status) const;
|
||||
|
||||
@ -169,7 +171,7 @@ class SessionManager {
|
||||
void on_add_sink(const StreamSink& sink, const StreamInfo& info);
|
||||
void on_remove_sink(const StreamInfo& info);
|
||||
|
||||
void on_ptp_status_locked() const;
|
||||
void on_ptp_status_changed(const std::string& status) const;
|
||||
|
||||
void on_update_sources();
|
||||
|
||||
|
@ -20,5 +20,6 @@
|
||||
"mdns_enabled": true,
|
||||
"mac_addr": "00:00:00:00:00:00",
|
||||
"ip_addr": "127.0.0.1",
|
||||
"node_id": "AES67 daemon 007f0100"
|
||||
"node_id": "AES67 daemon 007f0100",
|
||||
"ptp_status_script": ""
|
||||
}
|
||||
|
@ -392,6 +392,7 @@ BOOST_AUTO_TEST_CASE(get_config) {
|
||||
auto syslog_proto = pt.get<std::string>("syslog_proto");
|
||||
auto syslog_server = pt.get<std::string>("syslog_server");
|
||||
auto status_file = pt.get<std::string>("status_file");
|
||||
auto ptp_status_script = pt.get<std::string>("ptp_status_script");
|
||||
auto interface_name = pt.get<std::string>("interface_name");
|
||||
auto mac_addr = pt.get<std::string>("mac_addr");
|
||||
auto ip_addr = pt.get<std::string>("ip_addr");
|
||||
@ -413,6 +414,7 @@ BOOST_AUTO_TEST_CASE(get_config) {
|
||||
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(ip_addr == "127.0.0.1", "config as excepcted");
|
||||
BOOST_CHECK_MESSAGE(ptp_status_script == "", "config as excepcted");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(get_ptp_status) {
|
||||
|
@ -20,5 +20,6 @@
|
||||
"mdns_enabled": false,
|
||||
"mac_addr": "00:00:00:00:00:00",
|
||||
"ip_addr": "127.0.0.1",
|
||||
"node_id": "AES67 daemon 007f0100"
|
||||
"node_id": "AES67 daemon 007f0100",
|
||||
"ptp_status_script": ""
|
||||
}
|
||||
|
@ -135,7 +135,7 @@ class Config extends Component {
|
||||
this.state.sapMcastAddr,
|
||||
this.state.sapInterval,
|
||||
this.state.mdnsEnabled)
|
||||
.then(response => toast.success('Config updated, daemon restart ...'));
|
||||
.then(response => toast.success('Applying new configuration ...'));
|
||||
}
|
||||
|
||||
render() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user