RAVENNAKIT
Loading...
Searching...
No Matches
ptp_instance.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: AGPL-3.0-or-later
2/*
3 * Project: RAVENNAKIT (RAVENNA / AES67 / ST2110-30 SDK)
4 * Copyright (c) 2024-2025 Sound on Digital
5 *
6 * This file is part of RAVENNAKIT.
7 *
8 * RAVENNAKIT is dual-licensed:
9 * 1) Under the terms of the GNU Affero General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version (the "AGPL License"); and
12 * 2) Under a commercial license from Sound on Digital, for customers who
13 * cannot (or do not wish to) comply with the AGPL License terms.
14 *
15 * If you obtained this file under the AGPL License, you may redistribute it
16 * and/or modify it under the terms of the AGPL License. See the LICENSE
17 * file in the project root for details.
18 *
19 * For commercial licensing, support, and other inquiries, please visit:
20 *
21 * https://ravennakit.com
22 *
23 */
24
25#pragma once
26
27#include "ptp_error.hpp"
28#include "ptp_local_clock.hpp"
29#include "ptp_port.hpp"
30#include "detail/ptp_stats.hpp"
39
40#include <boost/lockfree/spsc_value.hpp>
41
42namespace rav::ptp {
43
47class Instance {
48 public:
53 uint8_t domain_number {};
54 };
55
56 class Subscriber {
57 public:
58 virtual ~Subscriber() = default;
59
64 virtual void ptp_parent_changed(const ParentDs& parent) {
65 std::ignore = parent;
66 }
67
72 virtual void ptp_port_changed_state(const Port& port) {
73 std::ignore = port;
74 }
75
80 virtual void ptp_port_removed(const uint16_t port_number) {
81 std::ignore = port_number;
82 }
83
88 virtual void ptp_configuration_updated(const Configuration& config) {
89 std::ignore = config;
90 }
91
96 virtual void ptp_stats_updated(const Stats& ptp_stats) {
97 std::ignore = ptp_stats;
98 }
99
105
106 private:
107 friend class Instance;
108 boost::lockfree::spsc_value<LocalClock> local_clock_buffer_;
109 LocalClock local_clock_;
110 };
111
117 explicit Instance(boost::asio::io_context& io_context);
118
120
126 [[nodiscard]] bool subscribe(Subscriber* subscriber);
127
134 [[nodiscard]] bool unsubscribe(const Subscriber* subscriber);
135
140 [[nodiscard]] tl::expected<void, std::string> set_configuration(Configuration config);
141
145 [[nodiscard]] const Configuration& get_configuration() const;
146
154 [[nodiscard]] tl::expected<void, Error> add_port(uint16_t port_number, const boost::asio::ip::address_v4& interface_address);
155
163 [[nodiscard]] tl::expected<void, Error> add_or_update_port(uint16_t port_number, const boost::asio::ip::address_v4& interface_address);
164
171 [[nodiscard]] tl::expected<void, Error> update_ports(const std::vector<ip_address_v4>& ports);
172
177 [[nodiscard]] bool has_port(uint16_t port_number) const;
178
185 [[nodiscard]] bool remove_port(uint16_t port_number);
186
190 [[nodiscard]] size_t get_port_count() const;
191
198 [[nodiscard]] bool set_port_interface(uint16_t port_number, const boost::asio::ip::address_v4& interface_address) const;
199
203 [[nodiscard]] const DefaultDs& get_default_ds() const;
204
208 [[nodiscard]] const ParentDs& get_parent_ds() const;
209
213 [[nodiscard]] const TimePropertiesDs& get_time_properties_ds() const;
214
220 bool set_recommended_state(StateDecisionCode state_decision_code, const std::optional<AnnounceMessage>& announce_message);
221
226
232 [[nodiscard]] bool should_process_ptp_messages(const MessageHeader& header) const;
233
241
245 [[nodiscard]] Timestamp get_local_ptp_time() const;
246
252
253 private:
254 boost::asio::io_context& io_context_;
255 Configuration config_;
256 boost::asio::steady_timer state_decision_timer_;
257 DefaultDs default_ds_;
258 CurrentDs current_ds_;
259 ParentDs parent_ds_;
260 TimePropertiesDs time_properties_ds_;
261 std::vector<std::unique_ptr<Port>> ports_;
262 LocalClock local_clock_;
263 Stats ptp_stats_;
264 Throttle<void> stats_callback_throttle_ {std::chrono::seconds(5)};
265 SubscriberList<Subscriber> subscribers_;
266
267 [[nodiscard]] uint16_t get_next_available_port_number() const;
268 void schedule_state_decision_timer();
269};
270
271void tag_invoke(const boost::json::value_from_tag&, boost::json::value& jv, const Instance::Configuration& config);
272
273Instance::Configuration tag_invoke(const boost::json::value_to_tag<Instance::Configuration>&, const boost::json::value& jv);
274
275} // namespace rav::ptp
Super basic list of subscribers.
A class that throttles a value to a given interval.
Definition throttle.hpp:36
virtual void ptp_port_changed_state(const Port &port)
Called when the state of a port changes.
virtual void ptp_parent_changed(const ParentDs &parent)
Called when the parent of the PTP instance changes.
virtual void ptp_stats_updated(const Stats &ptp_stats)
Called at a regular interval when the PTP stats are updated.
virtual void ptp_port_removed(const uint16_t port_number)
Called when a port was removed.
const LocalClock & get_local_clock()
virtual ~Subscriber()=default
virtual void ptp_configuration_updated(const Configuration &config)
Called when the configuration was updated.
bool subscribe(Subscriber *subscriber)
Adds a subscriber to the PTP instance.
const ParentDs & get_parent_ds() const
Instance(boost::asio::io_context &io_context)
Constructs a PTP instance.
bool set_port_interface(uint16_t port_number, const boost::asio::ip::address_v4 &interface_address) const
Sets the network interface for port with given port number.
tl::expected< void, Error > add_port(uint16_t port_number, const boost::asio::ip::address_v4 &interface_address)
Adds a port to the PTP instance.
const Configuration & get_configuration() const
State get_state_for_decision_code(StateDecisionCode code) const
Determines what the state of a port should be based on the state decision code and the internal state...
void update_local_ptp_clock(const Measurement< double > &measurement)
Adjusts the PTP clock of the PTP instance based on the mean delay and offset from the master.
bool should_process_ptp_messages(const MessageHeader &header) const
Determines whether the PTP instance should process the given PTP message.
const DefaultDs & get_default_ds() const
Timestamp get_local_ptp_time() const
tl::expected< void, std::string > set_configuration(Configuration config)
Updates the configuration of the sender.
bool has_port(uint16_t port_number) const
void execute_state_decision_event()
Execute a state decision event on all ports in the PTP instance.
bool remove_port(uint16_t port_number)
Removes a port from the PTP instance.
tl::expected< void, Error > update_ports(const std::vector< ip_address_v4 > &ports)
Updates the ports to match the entries in given array.
bool unsubscribe(const Subscriber *subscriber)
Removes a subscriber from the PTP instance.
size_t get_port_count() const
tl::expected< void, Error > add_or_update_port(uint16_t port_number, const boost::asio::ip::address_v4 &interface_address)
Adds or updates a port.
bool set_recommended_state(StateDecisionCode state_decision_code, const std::optional< AnnounceMessage > &announce_message)
Updates the data sets of the PTP instance based on the state decision code.
const TimePropertiesDs & get_time_properties_ds() const
Maintains a local clock corrected to the timebase of another time source, most likely a PTP master cl...
void tag_invoke(const boost::json::value_from_tag &, boost::json::value &jv, const Instance::Configuration &config)
StateDecisionCode
State decision codes.
State
The PTP state.
Represents the data set as described in IEEE1588-2019: 8.2.2.
Represents the default data set as described in IEEE1588-2019: 8.2.1.
Defines the configuration of the PTP instance (of parameters which need to be persisted).
Provides a view over given data, interpreting it as a PTP message header.
Represents the parent data set as described in IEEE1588-2019: 8.2.3.
Holds different statistics of PTP measurements.
Definition ptp_stats.hpp:36
Represents the time properties data set as described in IEEE1588-2019: 8.2.4.
A PTP timestamp, consisting of a seconds and nanoseconds part.