Added handling of multicast membership for PTP messages.

Limited PTP domain value to the range 0 - 127.
This commit is contained in:
Andrea Bondavalli 2020-02-02 07:12:36 -08:00
parent 52e8868b5e
commit 0c32e8e698
7 changed files with 37 additions and 11 deletions

View File

@ -68,6 +68,8 @@ std::shared_ptr<Config> Config::parse(const std::string& filename) {
if (ip::address_v4::from_string(config.rtp_mcast_base_.c_str()).to_ulong() ==
INADDR_NONE)
config.rtp_mcast_base_ = "239.1.0.1";
if (config.ptp_domain_ > 127)
config.ptp_domain_ = 0;
auto [mac_addr, mac_str] = get_interface_mac(config.interface_name_);
if (mac_str.empty()) {

View File

@ -137,6 +137,11 @@ bool HttpServer::start() {
svr_.Post("/api/ptp/config", [this](const Request& req, Response& res) {
try {
PTPConfig ptpConfig = json_to_ptp_config(req.body);
auto ret = session_manager_->set_ptp_config(ptpConfig);
if (ret) {
set_error(ret, "failed to set ptp config", res);
return;
}
Config config(*config_);
config.set_ptp_domain(ptpConfig.domain);
config.set_ptp_dscp(ptpConfig.dscp);
@ -144,11 +149,6 @@ bool HttpServer::start() {
set_error(500, "failed to save config", res);
return;
}
auto ret = session_manager_->set_ptp_config(ptpConfig);
if (ret) {
set_error(ret, "failed to set ptp config", res);
return;
}
set_headers(res);
} catch (const std::runtime_error& e) {
set_error(400, e.what(), res);

View File

@ -426,7 +426,7 @@ static void parse_json_sources(boost::property_tree::ptree& pt,
v.second.get_child("map")) {
source.map.emplace_back(std::stoi(vm.second.data()));
}
sources.emplace_back(std::move(source));
sources.emplace_back(std::move(source));
}
}

View File

@ -1 +1,4 @@
# Note:
# currently ptp4l disables IP_MULTICAST_LOOP, so sockets on the same host cannot receive ptp4l traffic.
# Only exception is for lo network interface.
sudo ptp4l -i $1 -m -l7 -E -S

View File

@ -918,6 +918,11 @@ bool SessionManager::worker() {
sap_.set_multicast_interface(config_->get_ip_addr_str());
// join PTP multicast address for specific domain
uint32_t ptp_addr = ip::address_v4::from_string(ptp_dflt_mcast_addr).to_ulong() +
config_->get_ptp_domain();
igmp_.join(config_->get_ip_addr_str(), ip::address_v4(ptp_addr).to_string());
while (running_) {
// check if it's time to update the PTP status
if (std::chrono::duration_cast<second_t> (clock_::now() - ptp_timepoint).count() >
@ -944,6 +949,7 @@ bool SessionManager::worker() {
// update PTP clock status
std::unique_lock ptp_lock(ptp_mutex_);
// update status
ptp_status_.gmid = ptp_clock_id;
ptp_status_.jitter = ptp_status.i32Jitter;
std::string new_ptp_status;
@ -967,9 +973,17 @@ bool SessionManager::worker() {
(void)driver_->set_sample_rate(driver_->get_current_sample_rate());
}
}
// update config
ptp_config_.domain = ptp_config.ui8Domain;
ptp_config_.dscp = ptp_config.ui8DSCP;
// update PTP multicast join
uint32_t new_ptp_addr = ip::address_v4::from_string(ptp_dflt_mcast_addr).to_ulong() +
ptp_config.ui8Domain;
if (new_ptp_addr != ptp_addr) {
// leave old PTP multicast address for specific domain
igmp_.leave(config_->get_ip_addr_str(), ip::address_v4(ptp_addr).to_string());
ptp_addr = new_ptp_addr;
// join new PTP multicast address for specific domain
igmp_.join(config_->get_ip_addr_str(), ip::address_v4(ptp_addr).to_string());
}
}
ptp_interval = 10;
}
@ -1010,6 +1024,8 @@ bool SessionManager::worker() {
// send deletion for this source
sap_.deletion(static_cast<uint16_t>(msg_id_hash), addr, sdp);
}
// leave PTP primary multicast
igmp_.leave(config_->get_ip_addr_str(), ip::address_v4(ptp_addr).to_string());
return true;
}

View File

@ -147,6 +147,8 @@ class SessionManager {
size_t process_sap();
protected:
constexpr static const char ptp_dflt_mcast_addr[] = "224.0.1.129";
std::string get_removed_source_sdp_(uint32_t id, uint32_t src_addr) const;
std::string get_source_sdp_(uint32_t id, const StreamInfo& info) const;
StreamSource get_source_(uint8_t id, const StreamInfo& info) const;
@ -157,7 +159,10 @@ class SessionManager {
// singleton, use create() to build
SessionManager(std::shared_ptr<DriverManager> driver,
std::shared_ptr<Config> config)
: driver_(driver), config_(config){};
: driver_(driver), config_(config){
ptp_config_.domain = config->get_ptp_domain();
ptp_config_.dscp = config->get_ptp_dscp();
};
std::shared_ptr<DriverManager> driver_;
std::shared_ptr<Config> config_;

View File

@ -95,7 +95,7 @@ class PTP extends Component {
</tr>
<tr>
<th align="left"> <label>Domain</label> </th>
<th align="left"> <input type='number' min='0' max='255' className='input-number' value={this.state.domain} onChange={e => this.setState({domain: e.target.value, domainErr: !e.currentTarget.checkValidity()})} required/> </th>
<th align="left"> <input type='number' min='0' max='127' className='input-number' value={this.state.domain} onChange={e => this.setState({domain: e.target.value, domainErr: !e.currentTarget.checkValidity()})} required/> </th>
</tr>
<tr>
<th align="left"> <label>DSCP</label> </th>