diff --git a/daemon/README.md b/daemon/README.md index e442d6c..4415aaf 100644 --- a/daemon/README.md +++ b/daemon/README.md @@ -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 ### Example diff --git a/daemon/browser.cpp b/daemon/browser.cpp index 3842704..420e01d 100644 --- a/daemon/browser.cpp +++ b/daemon/browser.cpp @@ -101,9 +101,9 @@ bool Browser::worker() { duration_cast(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 diff --git a/daemon/config.cpp b/daemon/config.cpp index 9889958..c364a93 100644 --- a/daemon/config.cpp +++ b/daemon/config.cpp @@ -36,7 +36,8 @@ using namespace boost::asio; -std::shared_ptr Config::parse(const std::string& filename) { +std::shared_ptr Config::parse(const std::string& filename, + bool driver_restart) { Config config; std::ifstream jsonstream(filename); @@ -104,20 +105,43 @@ std::shared_ptr 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); } -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; } diff --git a/daemon/config.hpp b/daemon/config.hpp index 7b74d0c..6502071 100644 --- a/daemon/config.hpp +++ b/daemon/config.hpp @@ -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 parse(const std::string& filename); + static std::shared_ptr 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 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 diff --git a/daemon/daemon.conf b/daemon/daemon.conf index 95f3343..7a02015 100644 --- a/daemon/daemon.conf +++ b/daemon/daemon.conf @@ -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" } diff --git a/daemon/driver_handler.cpp b/daemon/driver_handler.cpp index dd6b82a..0ba8690 100644 --- a/daemon/driver_handler.cpp +++ b/daemon/driver_handler.cpp @@ -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(); diff --git a/daemon/driver_handler.hpp b/daemon/driver_handler.hpp index b7957f7..501ab05 100644 --- a/daemon/driver_handler.hpp +++ b/daemon/driver_handler.hpp @@ -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, diff --git a/daemon/driver_manager.cpp b/daemon/driver_manager.cpp index 9a1be6f..9715db0 100644 --- a/daemon/driver_manager.cpp +++ b/daemon/driver_manager.cpp @@ -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() { diff --git a/daemon/driver_manager.hpp b/daemon/driver_manager.hpp index 938c2e2..fda9c8d 100644 --- a/daemon/driver_manager.hpp +++ b/daemon/driver_manager.hpp @@ -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); diff --git a/daemon/http_server.cpp b/daemon/http_server.cpp index b8e36da..2a9e005 100644 --- a/daemon/http_server.cpp +++ b/daemon/http_server.cpp @@ -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; } diff --git a/daemon/interface.cpp b/daemon/interface.cpp index 2211621..f5f9fb5 100644 --- a/daemon/interface.cpp +++ b/daemon/interface.cpp @@ -115,7 +115,6 @@ int get_interface_index(const std::string& interface_name) { return ifr.ifr_ifindex; } - std::pair, std::string> get_mac_from_arp_cache( const std::string& interface_name, const std::string& ip) { @@ -155,7 +154,6 @@ std::pair, 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; diff --git a/daemon/json.cpp b/daemon/json.cpp index 649ef29..68a16c7 100644 --- a/daemon/json.cpp +++ b/daemon/json.cpp @@ -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())); + } else if (key == "ptp_status_script") { + config.set_ptp_status_script( + remove_undesired_chars(val.get_value())); } else if (key == "mac_addr" || key == "ip_addr" || key == "node_id") { /* ignored */ } else { diff --git a/daemon/main.cpp b/daemon/main.cpp index 88299cd..58fa162 100644 --- a/daemon/main.cpp +++ b/daemon/main.cpp @@ -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 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()->default_value("/etc/daemon.conf"), - "daemon configuration file") - ("http_port,p", po::value(), "HTTP server port") - ("help,h", "Print this help message"); + desc.add_options()("version,v", "Print daemon version and exit")( + "config,c", po::value()->default_value("/etc/daemon.conf"), + "daemon configuration file")("http_port,p", po::value(), + "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")); } diff --git a/daemon/mdns_client.cpp b/daemon/mdns_client.cpp index 96e9621..224e7f4 100644 --- a/daemon/mdns_client.cpp +++ b/daemon/mdns_client.cpp @@ -25,7 +25,6 @@ #include "rtsp_client.hpp" #include "mdns_client.hpp" - #ifdef _USE_AVAHI_ void MDNSClient::resolve_callback(AvahiServiceResolver* r, AvahiIfIndex interface, diff --git a/daemon/mdns_server.cpp b/daemon/mdns_server.cpp index 2bf3341..9611d3d 100644 --- a/daemon/mdns_server.cpp +++ b/daemon/mdns_server.cpp @@ -25,7 +25,6 @@ #include "utils.hpp" #include "mdns_server.hpp" - #ifdef _USE_AVAHI_ struct AvahiLockGuard { AvahiLockGuard() = delete; diff --git a/daemon/rtsp_server.cpp b/daemon/rtsp_server.cpp index a35c509..c695245 100644 --- a/daemon/rtsp_server.cpp +++ b/daemon/rtsp_server.cpp @@ -15,7 +15,6 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . - #include "utils.hpp" #include "rtsp_server.hpp" diff --git a/daemon/scripts/ptp_status.sh b/daemon/scripts/ptp_status.sh new file mode 100755 index 0000000..679dd62 --- /dev/null +++ b/daemon/scripts/ptp_status.sh @@ -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 diff --git a/daemon/session_manager.cpp b/daemon/session_manager.cpp index 2c00a0e..f6a5a91 100644 --- a/daemon/session_manager.cpp +++ b/daemon/session_manager.cpp @@ -19,6 +19,7 @@ #define CPPHTTPLIB_PAYLOAD_MAX_LENGTH 4096 // max for SDP file +#include #include #include @@ -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(info.stream.m_byTTL); } - ss << "\na=rtpmap:" << static_cast(info.stream.m_byPayloadType) << " " - << info.stream.m_cCodec << "/" << sample_rate << "/" + ss << "\na=rtpmap:" << static_cast(info.stream.m_byPayloadType) + << " " << info.stream.m_cCodec << "/" << sample_rate << "/" << static_cast(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(config_->get_ptp_status_script().c_str()), + const_cast(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(); } } diff --git a/daemon/session_manager.hpp b/daemon/session_manager.hpp index 7dedd34..b580b14 100644 --- a/daemon/session_manager.hpp +++ b/daemon/session_manager.hpp @@ -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(); diff --git a/daemon/tests/daemon.conf b/daemon/tests/daemon.conf index 9ab940d..f4d2d72 100644 --- a/daemon/tests/daemon.conf +++ b/daemon/tests/daemon.conf @@ -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": "" } diff --git a/daemon/tests/daemon_test.cpp b/daemon/tests/daemon_test.cpp index b13568a..d633c13 100644 --- a/daemon/tests/daemon_test.cpp +++ b/daemon/tests/daemon_test.cpp @@ -392,6 +392,7 @@ BOOST_AUTO_TEST_CASE(get_config) { auto syslog_proto = pt.get("syslog_proto"); auto syslog_server = pt.get("syslog_server"); auto status_file = pt.get("status_file"); + auto ptp_status_script = pt.get("ptp_status_script"); auto interface_name = pt.get("interface_name"); auto mac_addr = pt.get("mac_addr"); auto ip_addr = pt.get("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) { diff --git a/test/daemon.conf b/test/daemon.conf index 0a118dc..3d3131f 100644 --- a/test/daemon.conf +++ b/test/daemon.conf @@ -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": "" } diff --git a/webui/src/Config.jsx b/webui/src/Config.jsx index 3bd7f56..2019c9e 100644 --- a/webui/src/Config.jsx +++ b/webui/src/Config.jsx @@ -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() {