Added "auto_sinks_update" to the daemon configuration parameters and to the WebUI.

JSON boolean specifying whether to enable or disable the automatic update of the configured Sinks.
When enabled the daemon will automatically update the configured Sinks according to the discovered remote sources via SAP and mDNS/RTSP updates.
The SDP Originator (o=) is used to match a Sink with the remote source/s.
This commit is contained in:
Andrea Bondavalli 2023-01-14 19:24:43 +01:00
parent 6ed3a9ef54
commit ffa8e80213
11 changed files with 51 additions and 19 deletions

View File

@ -50,7 +50,7 @@ The daemon can be cross-compiled for multiple platforms and implements the follo
* control and configuration of up to 64 multicast and unicast sources and sinks using the ALSA RAVENNA/AES67 driver via netlink
* session handling and SDP parsing and creation
* HTTP REST API for the daemon control and configuration
* SAP sources discovery and advertisement compatible with AES67 standard
* SAP sources discovery, update and advertisement compatible with AES67 standard
* mDNS sources discovery and advertisement (using Linux Avahi) compatible with Ravenna standard
* RTSP client and server to retrieve, return and update SDP files via DESCRIBE and ANNOUNCE methods according to Ravenna standard
* IGMP handling for SAP, PTP and RTP sessions

View File

@ -12,6 +12,7 @@ The daemon is responsible for:
* mDNS sources discovery and advertisement (using Linux Avahi) compatible with Ravenna standard
* RTSP client and server to retrieve, return and update SDP files via DESCRIBE and ANNOUNCE methods according to Ravenna standard
* IGMP handling for SAP, PTP and RTP sessions
* automatic update of Sinks based on discovered mDNS/SAP remote sources
## Configuration file ##
@ -187,7 +188,8 @@ Example
"ip_addr": "127.0.0.1",
"node_id": "AES67 daemon d9aca383",
"custom_node_id": "",
"ptp_status_script": "./scripts/ptp_status.sh"
"ptp_status_script": "./scripts/ptp_status.sh",
"auto_sinks_update": true
}
where:
@ -269,6 +271,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.
> **mauto\_sinks\_update**
> JSON boolean specifying whether to enable or disable the automatic update of the configured Sinks.
> **_NOTE:_** When enabled the daemon will automatically update the configured Sinks according to the discovered remote sources via SAP and mDNS/RTSP updates. The SDP Originator (o=) is used to match a Sink with the remote source/s.
> **custom\_node\_id**
> JSON string specifying a custom node identifier used to identify mDNS, SAP and SDP services announced by the daemon.
> When this parameter is empty the *node_id* is automatically generated by the daemon based on the current IP address.

View File

@ -54,6 +54,7 @@ class Config {
const std::string& get_config_filename() const { return config_filename_; };
const std::string& get_custom_node_id() const { return custom_node_id_; };
std::string get_node_id() const;
bool get_auto_sinks_update() const { return auto_sinks_update_; };
/* attributes set during init */
const std::array<uint8_t, 6>& get_mac_addr() const { return mac_addr_; };
@ -122,6 +123,9 @@ class Config {
void set_custom_node_id(const std::string& node_id) {
custom_node_id_ = node_id;
};
void set_auto_sinks_update(bool auto_sinks_update) {
auto_sinks_update_ = auto_sinks_update;
};
void set_driver_restart(bool restart) { driver_restart_ = restart; }
friend bool operator!=(const Config& lhs, const Config& rhs) {
@ -144,6 +148,7 @@ class Config {
lhs.get_status_file() != rhs.get_status_file() ||
lhs.get_interface_name() != rhs.get_interface_name() ||
lhs.get_mdns_enabled() != rhs.get_mdns_enabled() ||
lhs.get_auto_sinks_update() != rhs.get_auto_sinks_update() ||
lhs.get_custom_node_id() != rhs.get_custom_node_id();
};
friend bool operator==(const Config& lhs, const Config& rhs) {
@ -174,6 +179,7 @@ class Config {
std::string ptp_status_script_;
std::string custom_node_id_;
std::string node_id_;
bool auto_sinks_update_{true};
/* set during init */
std::array<uint8_t, 6> mac_addr_{0, 0, 0, 0, 0, 0};

View File

@ -19,5 +19,6 @@
"interface_name": "lo",
"mdns_enabled": true,
"custom_node_id": "",
"ptp_status_script": "./scripts/ptp_status.sh"
"ptp_status_script": "./scripts/ptp_status.sh",
"auto_sinks_update": true
}

View File

@ -99,13 +99,16 @@ std::string config_to_json(const Config& config) {
<< ",\n \"interface_name\": \""
<< escape_json(config.get_interface_name()) << "\""
<< ",\n \"mdns_enabled\": " << std::boolalpha << config.get_mdns_enabled()
<< ",\n \"custom_node_id\": \"" << escape_json(config.get_custom_node_id()) << "\""
<< ",\n \"custom_node_id\": \""
<< escape_json(config.get_custom_node_id()) << "\""
<< ",\n \"node_id\": \"" << escape_json(config.get_node_id()) << "\""
<< ",\n \"ptp_status_script\": \""
<< escape_json(config.get_ptp_status_script()) << "\""
<< ",\n \"mac_addr\": \"" << escape_json(config.get_mac_addr_str()) << "\""
<< ",\n \"mac_addr\": \"" << escape_json(config.get_mac_addr_str())
<< "\""
<< ",\n \"ip_addr\": \"" << escape_json(config.get_ip_addr_str()) << "\""
<< "\n}\n";
<< ",\n \"auto_sinks_update\": " << std::boolalpha
<< config.get_auto_sinks_update() << "\n}\n";
return ss.str();
}
@ -327,6 +330,8 @@ Config json_to_config_(std::istream& js, Config& config) {
} else if (key == "custom_node_id") {
config.set_custom_node_id(
remove_undesired_chars(val.get_value<std::string>()));
} else if (key == "auto_sinks_update") {
config.set_auto_sinks_update(val.get_value<bool>());
} else if (key == "mac_addr" || key == "ip_addr" || key == "node_id") {
/* ignored */
} else {

View File

@ -1055,12 +1055,14 @@ std::list<StreamSink> SessionManager::get_updated_sinks(
}
void SessionManager::update_sinks(const std::list<RemoteSource>& sources_list) {
if (config_->get_auto_sinks_update()) {
auto sinks_list = get_updated_sinks(sources_list);
for (auto& sink : sinks_list) {
// Re-add sink with new SDP, since the sink.id is the same there will be
// an update
add_sink(sink);
}
}
}
void SessionManager::on_update_sources() {

View File

@ -18,9 +18,10 @@
"status_file": "",
"interface_name": "lo",
"mdns_enabled": true,
"mac_addr": "00:00:00:00:00:00",
"ip_addr": "127.0.0.1",
"custom_node_id": "test node",
"node_id": "test node",
"ptp_status_script": ""
"ptp_status_script": "",
"mac_addr": "00:00:00:00:00:00",
"ip_addr": "127.0.0.1",
"auto_sinks_update": true
}

View File

@ -398,6 +398,7 @@ BOOST_AUTO_TEST_CASE(get_config) {
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");
auto auto_sinks_update = pt.get<bool>("auto_sinks_update");
BOOST_CHECK_MESSAGE(http_port == 9999, "config as excepcted");
// BOOST_CHECK_MESSAGE(log_severity == 5, "config as excepcted");
BOOST_CHECK_MESSAGE(playout_delay == 0, "config as excepcted");
@ -419,6 +420,7 @@ BOOST_AUTO_TEST_CASE(get_config) {
BOOST_CHECK_MESSAGE(ptp_status_script == "", "config as excepcted");
BOOST_CHECK_MESSAGE(node_id == "test node", "config as excepcted");
BOOST_CHECK_MESSAGE(custom_node_id == "test node", "config as excepcted");
BOOST_CHECK_MESSAGE(auto_sinks_update == true, "config as excepcted");
}
BOOST_AUTO_TEST_CASE(get_ptp_status) {

View File

@ -22,5 +22,6 @@
"ip_addr": "127.0.0.1",
"node_id": "AES67 daemon 007f0100",
"custom_node_id": "",
"ptp_status_script": ""
"ptp_status_script": "",
"auto_sinks_update": true
}

View File

@ -59,7 +59,8 @@ class Config extends Component {
ipAddr: '',
errors: 0,
isConfigLoading: false,
isVersionLoading: false
isVersionLoading: false,
autoSinksUpdate: false
};
this.onSubmit = this.onSubmit.bind(this);
this.inputIsValid = this.inputIsValid.bind(this);
@ -104,6 +105,7 @@ class Config extends Component {
macAddr: data.mac_addr,
ipAddr: data.ip_addr,
nodeId: data.node_id,
autoSinksUpdate: data.auto_sinks_update,
isConfigLoading: false
}))
.catch(err => this.setState({isConfigLoading: false}));
@ -139,7 +141,8 @@ class Config extends Component {
this.state.sapMcastAddr,
this.state.sapInterval,
this.state.mdnsEnabled,
this.state.customNodeId)
this.state.customNodeId,
this.state.autoSinksUpdate)
.then(response => toast.success('Applying new configuration ...'));
}
@ -226,6 +229,10 @@ class Config extends Component {
<th align="left"> <label>mDNS enabled</label> </th>
<th align="left"> <input type="checkbox" onChange={e => this.setState({mdnsEnabled: e.target.checked})} checked={this.state.mdnsEnabled ? true : undefined}/> </th>
</tr>
<tr height="35">
<th align="left"> <label>Automaitc update of Sinks</label> </th>
<th align="left"> <input type="checkbox" onChange={e => this.setState({autoSinksUpdate: e.target.checked})} checked={this.state.autoSinksUpdate ? true : undefined}/> </th>
</tr>
<tr>
<th align="left"> <label>Network Interface</label> </th>
<th align="left"> <input value={this.state.interfaceName} disabled/> </th>

View File

@ -84,7 +84,7 @@ export default class RestAPI {
});
}
static setConfig(log_severity, syslog_proto, syslog_server, rtp_mcast_base, rtp_port, rtsp_port, playout_delay, tic_frame_size_at_1fs, sample_rate, max_tic_frame_size, sap_mcast_addr, sap_interval, mdns_enabled, custom_node_id) {
static setConfig(log_severity, syslog_proto, syslog_server, rtp_mcast_base, rtp_port, rtsp_port, playout_delay, tic_frame_size_at_1fs, sample_rate, max_tic_frame_size, sap_mcast_addr, sap_interval, mdns_enabled, custom_node_id, auto_sinks_update) {
return this.doFetch(config, {
body: JSON.stringify({
log_severity: parseInt(log_severity, 10),
@ -100,7 +100,8 @@ export default class RestAPI {
sap_mcast_addr: sap_mcast_addr,
sap_interval: parseInt(sap_interval, 10),
custom_node_id: custom_node_id,
mdns_enabled: mdns_enabled
mdns_enabled: mdns_enabled,
auto_sinks_update: auto_sinks_update
}),
method: 'POST'
}).catch(err => {