From b0ccd8e4d13828669d00bdbbdbe701a7970f6d43 Mon Sep 17 00:00:00 2001 From: Mike Purvis Date: Fri, 30 May 2025 18:30:49 -0400 Subject: [PATCH 1/5] Basic build pipeline --- .github/workflows/build.yaml | 38 ++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 .github/workflows/build.yaml diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml new file mode 100644 index 00000000..17717a31 --- /dev/null +++ b/.github/workflows/build.yaml @@ -0,0 +1,38 @@ +#------------------------------------------------------------------------------ +# .github/workflows/pure.yaml +#------------------------------------------------------------------------------ +# Workflow that builds tally-pure. There's no need to build this for multiple +# arches since it's just textual scripts. +#------------------------------------------------------------------------------ +# Authors: Mike Purvis +# Copyright (c) 2025, Simbe Robotics, Inc. +#------------------------------------------------------------------------------ +name: Build + +on: push + +jobs: + deb: + runs-on: ubuntu-24.04 + + steps: + - uses: actions/checkout@v4 + + - run: | + sudo apt-get update + sudo apt-get install -yq build-essential devscripts equivs + + - name: Install build dependencies + run: | + sudo mk-build-deps --install \ + --tool='apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends -yq' + + - run: dpkg-buildpackage -uc -b + + - name: Show contents + run: dpkg -c ../ptpd_*.deb + + - name: Push deb to gemfury + run: | + echo "need token" + # curl -F package=@$(ls ../ptpd_*.deb) https://${{ secrets.GEMFURY_API_KEY }}@push.fury.io/simberobotics From 6229d6c301848e29dcdc6a943b16dde67dbf5f6d Mon Sep 17 00:00:00 2001 From: Mike Purvis Date: Fri, 30 May 2025 18:51:41 -0400 Subject: [PATCH 2/5] Add version check --- .github/workflows/build.yaml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 17717a31..46149b66 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -32,7 +32,15 @@ jobs: - name: Show contents run: dpkg -c ../ptpd_*.deb - - name: Push deb to gemfury + - name: Push deb to gemfury on tag + if: startsWith(github.ref, 'refs/tags/') run: | - echo "need token" - # curl -F package=@$(ls ../ptpd_*.deb) https://${{ secrets.GEMFURY_API_KEY }}@push.fury.io/simberobotics + tag="${{ github.ref_name }}" + version="$(dpkg-parsechangelog -SVersion)" + + if [ "$tag" != "$version" ]; then + echo "::error ::Tag '$tag' does not match changelog version '$version'" + exit 1 + fi + + #curl -F package=@$(ls ../ptpd_*.deb) https://${{ secrets.GEMFURY_API_KEY }}@push.fury.io/simberobotics From 511be8aa8627a48cf13299527bf850a60a34d7eb Mon Sep 17 00:00:00 2001 From: Mike Purvis Date: Fri, 30 May 2025 19:10:27 -0400 Subject: [PATCH 3/5] Add systemd unit and conffile --- .gitignore | 1 + debian/ptpd.default | 7 - debian/ptpd.init | 155 -------- debian/ptpd.install | 1 + debian/ptpd.service | 15 + simbe/ptpd.conf | 840 ++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 857 insertions(+), 162 deletions(-) delete mode 100644 debian/ptpd.default delete mode 100755 debian/ptpd.init create mode 100644 debian/ptpd.service create mode 100644 simbe/ptpd.conf diff --git a/.gitignore b/.gitignore index fb984185..14340a68 100644 --- a/.gitignore +++ b/.gitignore @@ -45,3 +45,4 @@ debian/ptpd.debhelper.log debian/ptpd debian/files debian/ptpd.substvars +debian/ptpd.postrm.debhelper diff --git a/debian/ptpd.default b/debian/ptpd.default deleted file mode 100644 index 58eda7da..00000000 --- a/debian/ptpd.default +++ /dev/null @@ -1,7 +0,0 @@ -# /etc/default/ptpd - -# Set to "yes" to actually start ptpd automatically -START_DAEMON=no - -# Add command line options for ptpd -PTPD_OPTS="" diff --git a/debian/ptpd.init b/debian/ptpd.init deleted file mode 100755 index 47bbe255..00000000 --- a/debian/ptpd.init +++ /dev/null @@ -1,155 +0,0 @@ -#!/bin/sh -# -# /etc/init.d script for ptpd - -### BEGIN INIT INFO -# Provides: ptpd -# Required-Start: $network $remote_fs -# Required-Stop: $network $remote_fs -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: start and stop ptpd -# Description: ptpd is the Precision Time Protocol daemon (IEEE1588-2008) -### END INIT INFO - -PATH=/sbin:/usr/sbin:/bin:/usr/bin -DESC="Precision Time Protocol daemon" -NAME=ptpd -DAEMON=/usr/sbin/$NAME -PIDFILE=/var/run/$NAME.pid -SCRIPTNAME=/etc/init.d/$NAME - -# Exit if the package is not installed -[ -x "$DAEMON" ] || exit 0 - -# Read configuration variable file if it is present -[ -r /etc/default/$NAME ] && . /etc/default/$NAME - -# Load the VERBOSE setting and other rcS variables -. /lib/init/vars.sh - -# Define LSB log_* functions. -# Depend on lsb-base (>= 3.2-14) to ensure that this file is present -# and status_of_proc is working. -. /lib/lsb/init-functions - -# Only active on START_DAEMON -[ "$START_DAEMON" = "yes" ] || exit 0 - -# -# Function that starts the daemon/service -# -do_start() -{ - # Return - # 0 if daemon has been started - # 1 if daemon was already running - # 2 if daemon could not be started - start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \ - || return 1 - start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \ - $PTPD_OPTS \ - || return 2 - # Add code here, if necessary, that waits for the process to be ready - # to handle requests from services started subsequently which depend - # on this one. As a last resort, sleep for some time. -} - -# -# Function that stops the daemon/service -# -do_stop() -{ - # Return - # 0 if daemon has been stopped - # 1 if daemon was already stopped - # 2 if daemon could not be stopped - # other if a failure occurred - start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME - RETVAL="$?" - [ "$RETVAL" = 2 ] && return 2 - # Wait for children to finish too if this is a daemon that forks - # and if the daemon is only ever run from this initscript. - # If the above conditions are not satisfied then add some other code - # that waits for the process to drop all resources that could be - # needed by services started subsequently. A last resort is to - # sleep for some time. - start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON - [ "$?" = 2 ] && return 2 - # Many daemons don't delete their pidfiles when they exit. - rm -f $PIDFILE - return "$RETVAL" -} - -# -# Function that sends a SIGHUP to the daemon/service -# -do_reload() { - # - # If the daemon can reload its configuration without - # restarting (for example, when it is sent a SIGHUP), - # then implement that here. - # - start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME - return 0 -} - -case "$1" in - start) - [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" - do_start - case "$?" in - 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; - 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; - esac - ;; - stop) - [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" - do_stop - case "$?" in - 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; - 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; - esac - ;; - status) - status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $? - ;; - #reload|force-reload) - # - # If do_reload() is not implemented then leave this commented out - # and leave 'force-reload' as an alias for 'restart'. - # - #log_daemon_msg "Reloading $DESC" "$NAME" - #do_reload - #log_end_msg $? - #;; - restart|force-reload) - # - # If the "reload" option is implemented then remove the - # 'force-reload' alias - # - log_daemon_msg "Restarting $DESC" "$NAME" - do_stop - case "$?" in - 0|1) - do_start - case "$?" in - 0) log_end_msg 0 ;; - 1) log_end_msg 1 ;; # Old process is still running - *) log_end_msg 1 ;; # Failed to start - esac - ;; - *) - # Failed to stop - log_end_msg 1 - ;; - esac - ;; - *) - #echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2 - echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2 - exit 3 - ;; -esac - -: diff --git a/debian/ptpd.install b/debian/ptpd.install index 6275a4aa..df391ab3 100644 --- a/debian/ptpd.install +++ b/debian/ptpd.install @@ -1 +1,2 @@ src/ptpd2 usr/sbin +simbe/ptpd.conf etc diff --git a/debian/ptpd.service b/debian/ptpd.service new file mode 100644 index 00000000..1890bb25 --- /dev/null +++ b/debian/ptpd.service @@ -0,0 +1,15 @@ +[Unit] +Description=Precision Time Protocol Daemon +Wants=network-online.target +After=network.target network-online.target ntpdate.service sntp.service ntp.service chronyd.service +Conflicts=ptp4l.service + +[Service] +Type=simple +ExecStart=/usr/sbin/ptpd --global:lock_file=/var/run/ptpd.pid -c /etc/ptpd.conf --foreground +Restart=on-failure +CPUAffinity=0 +Nice=-19 + +[Install] +WantedBy=multi-user.target diff --git a/simbe/ptpd.conf b/simbe/ptpd.conf new file mode 100644 index 00000000..015b0220 --- /dev/null +++ b/simbe/ptpd.conf @@ -0,0 +1,840 @@ +; ================================================== +; PTPDv2 version 2.3.2-simbe-2 default configuration +; ================================================== +; NOTE: the following settings are affected by ptpengine:preset selection: +; ptpengine:slave_only +; clock:no_adjust +; ptpengine:clock_class - allowed range and default value +; To see all preset settings, run ptpd -H (--long-help) + +; Network interface to use - eth0, igb0 etc. (required). +ptpengine:interface = eth0 + +; Backup network interface to use - eth0, igb0 etc. When no GM available, +; slave will keep alternating between primary and secondary until a GM is found. +; +ptpengine:backup_interface = + +; PTP engine preset: +; none = Defaults, no clock class restrictions +; masteronly = Master, passive when not best master (clock class 0..127) +; masterslave = Full IEEE 1588 implementation: +; Master, slave when not best master +; (clock class 128..254) +; slaveonly = Slave only (clock class 255 only) +; +; Options: none masteronly masterslave slaveonly +ptpengine:preset = masteronly + +; Transport type for PTP packets. Ethernet transport requires libpcap support. +; Options: ipv4 ethernet +ptpengine:transport = ipv4 + +; Enable TransportSpecific field compatibility with 802.1AS / AVB (requires Ethernet transport) +ptpengine:dot1as = N + +; Disable PTP port. Causes the PTP state machine to stay in PTP_DISABLED state indefinitely, +; until it is re-enabled via configuration change or ENABLE_PORT management message. +ptpengine:disabled = N + +; IP transmission mode (requires IP transport) - hybrid mode uses +; multicast for sync and announce, and unicast for delay request and +; response; unicast mode uses unicast for all transmission. +; When unicast mode is selected, destination IP(s) may need to be configured +; (ptpengine:unicast_destinations). +; Options: multicast unicast hybrid +ptpengine:ip_mode = multicast + +; Enable unicast negotiation support using signaling messages +; +ptpengine:unicast_negotiation = N + +; When using unicast negotiation (slave), accept PTP messages from any master. +; By default, only messages from acceptable masters (ptpengine:unicast_destinations) +; are accepted, and only if transmission was granted by the master +; +ptpengine:unicast_any_master = N + +; PTP port number wildcard mask applied onto port identities when running +; unicast negotiation: allows multiple port identities to be accepted as one. +; This option can be used as a workaround where a node sends signaling messages and +; timing messages with different port identities +ptpengine:unicast_port_mask = 0 + +; Disable Best Master Clock Algorithm for unicast masters: +; Only effective for masteronly preset - all Announce messages +; will be ignored and clock will transition directly into MASTER state. +; +ptpengine:disable_bmca = N + +; When unicast negotiation enabled on a master clock, +; reply to transmission requests also in LISTENING state. +ptpengine:unicast_negotiation_listening = N + +; Use libpcap for sending and receiving traffic (automatically enabled +; in Ethernet mode). +ptpengine:use_libpcap = N + +; Disable UDP checksum validation on UDP sockets (Linux only). +; Workaround for situations where a node (like Transparent Clock). +; does not rewrite checksums +; +ptpengine:disable_udp_checksums = Y + +; Delay detection mode used - use DELAY_DISABLED for syntonisation only +; (no full synchronisation). +; Options: E2E P2P DELAY_DISABLED +ptpengine:delay_mechanism = E2E + +; PTP domain number. +ptpengine:domain = 0 + +; PTP port number (part of PTP Port Identity - not UDP port). +; For ordinary clocks (single port), the default should be used, +; but when running multiple instances to simulate a boundary clock, +; The port number can be changed. +ptpengine:port_number = 1 + +; Port description (returned in the userDescription field of PORT_DESCRIPTION management message and USER_DESCRIPTION management message) - maximum 64 characters +ptpengine:port_description = ptpd + +; Usability extension: if enabled, a slave-only clock will accept +; masters from any domain, while preferring the configured domain, +; and preferring lower domain number. +; NOTE: this behaviour is not part of the standard. +ptpengine:any_domain = N + +; Slave only mode (sets clock class to 255, overriding value from preset). +ptpengine:slave_only = Y + +; Specify latency correction (nanoseconds) for incoming packets. +ptpengine:inbound_latency = 0 + +; Specify latency correction (nanoseconds) for outgoing packets. +ptpengine:outbound_latency = 0 + +; Apply an arbitrary shift (nanoseconds) to offset from master when +; in slave state. Value can be positive or negative - useful for +; correcting for antenna latencies, delay assymetry +; and IP stack latencies. This will not be visible in the offset +; from master value - only in the resulting clock correction. +ptpengine:offset_shift = 0 + +; Compatibility option: In slave state, always respect UTC offset +; announced by best master, even if the the +; currrentUtcOffsetValid flag is announced FALSE. +; NOTE: this behaviour is not part of the standard. +ptpengine:always_respect_utc_offset = Y + +; Compatibility extension to BMC algorithm: when enabled, +; BMC for both master and save clocks will prefer masters +; nannouncing currrentUtcOffsetValid as TRUE. +; NOTE: this behaviour is not part of the standard. +ptpengine:prefer_utc_offset_valid = N + +; Compatibility option: when enabled, ptpd will ignore +; Announce messages from masters announcing currentUtcOffsetValid +; as FALSE. +; NOTE: this behaviour is not part of the standard. +ptpengine:require_utc_offset_valid = N + +; Time (seconds) unicast messages are requested for by slaves +; when using unicast negotiation, and maximum time unicast message +; transmission is granted to slaves by masters +; +ptpengine:unicast_grant_duration = 300 + +; PTP announce message interval in master state. When using unicast negotiation, for +; slaves this is the minimum interval requested, and for masters +; this is the only interval granted. +; (expressed as log 2 i.e. -1=0.5s, 0=1s, 1=2s etc.) +ptpengine:log_announce_interval = 1 + +; Maximum Announce message interval requested by slaves when using unicast negotiation, +; (expressed as log 2 i.e. -1=0.5s, 0=1s, 1=2s etc.) +ptpengine:log_announce_interval_max = 5 + +; PTP announce receipt timeout announced in master state. +ptpengine:announce_receipt_timeout = 6 + +; PTP announce receipt timeout grace period in slave state: +; when announce receipt timeout occurs, disqualify current best GM, +; then wait n times announce receipt timeout before resetting. +; Allows for a seamless GM failover when standby GMs are slow +; to react. When set to 0, this option is not used. +ptpengine:announce_receipt_grace_period = 0 + +; PTP sync message interval in master state. When using unicast negotiation, for +; slaves this is the minimum interval requested, and for masters +; this is the only interval granted. +; (expressed as log 2 i.e. -1=0.5s, 0=1s, 1=2s etc.) +ptpengine:log_sync_interval = 0 + +; Maximum Sync message interval requested by slaves when using unicast negotiation, +; (expressed as log 2 i.e. -1=0.5s, 0=1s, 1=2s etc.) +ptpengine:log_sync_interval_max = 5 + +; Override the Delay Request interval announced by best master. +ptpengine:log_delayreq_override = N + +; Automatically override the Delay Request interval +; if the announced value is 127 (0X7F), such as in +; unicast messages (unless using unicast negotiation) +ptpengine:log_delayreq_auto = Y + +; Delay request interval used before receiving first delay response +; (expressed as log 2 i.e. -1=0.5s, 0=1s, 1=2s etc.) +ptpengine:log_delayreq_interval_initial = 0 + +; Minimum delay request interval announced when in master state, +; in slave state overrides the master interval, +; required in hybrid mode. When using unicast negotiation, for +; slaves this is the minimum interval requested, and for masters +; this is the minimum interval granted. +; (expressed as log 2 i.e. -1=0.5s, 0=1s, 1=2s etc.) +ptpengine:log_delayreq_interval = 0 + +; Maximum Delay Response interval requested by slaves when using unicast negotiation, +; (expressed as log 2 i.e. -1=0.5s, 0=1s, 1=2s etc.) +ptpengine:log_delayreq_interval_max = 5 + +; Minimum peer delay request message interval in peer to peer delay mode. +; When using unicast negotiation, this is the minimum interval requested, +; and the only interval granted. +; (expressed as log 2 i.e. -1=0.5s, 0=1s, 1=2s etc.) +ptpengine:log_peer_delayreq_interval = 1 + +; Maximum Peer Delay Response interval requested by slaves when using unicast negotiation, +; (expressed as log 2 i.e. -1=0.5s, 0=1s, 1=2s etc.) +ptpengine:log_peer_delayreq_interval_max = 5 + +; Foreign master record size (Maximum number of foreign masters). +ptpengine:foreignrecord_capacity = 5 + +; Specify Allan variance announced in master state. +ptpengine:ptp_allan_variance = 65535 + +; Clock accuracy range announced in master state. +; Options: ACC_25NS ACC_100NS ACC_250NS ACC_1US ACC_2_5US ACC_10US ACC_25US ACC_100US ACC_250US ACC_1MS ACC_2_5MS ACC_10MS ACC_25MS ACC_100MS ACC_250MS ACC_1S ACC_10S ACC_10SPLUS ACC_UNKNOWN +ptpengine:ptp_clock_accuracy = ACC_UNKNOWN + +; Underlying time source UTC offset announced in master state. +ptpengine:utc_offset = 0 + +; Underlying time source UTC offset validity announced in master state. +ptpengine:utc_offset_valid = N + +; Underlying time source time traceability announced in master state. +ptpengine:time_traceable = N + +; Underlying time source frequency traceability announced in master state. +ptpengine:frequency_traceable = N + +; Time scale announced in master state (with ARB, UTC properties +; are ignored by slaves). When clock class is set to 13 (application +; specific), this value is ignored and ARB is used. +; Options: PTP ARB +ptpengine:ptp_timescale = PTP + +; Time source announced in master state. +; Options: ATOMIC_CLOCK GPS TERRESTRIAL_RADIO PTP NTP HAND_SET OTHER INTERNAL_OSCILLATOR +ptpengine:ptp_timesource = INTERNAL_OSCILLATOR + +; Clock class - announced in master state. Always 255 for slave-only. +; Minimum, maximum and default values are controlled by presets. +; If set to 13 (application specific time source), announced +; time scale is always set to ARB. This setting controls the +; states a PTP port can be in. If below 128, port will only +; be in MASTER or PASSIVE states (master only). If above 127, +; port will be in MASTER or SLAVE states. +ptpengine:clock_class = 127 + +; Priority 1 announced in master state,used for Best Master +; Clock selection. +ptpengine:priority1 = 127 + +; Priority 2 announced in master state, used for Best Master +; Clock selection. +ptpengine:priority2 = 127 + +; Number of consecutive resets to LISTENING before full network reset +; +ptpengine:max_listen = 5 + +; Specify unicast slave addresses for unicast master operation, or unicast +; master addresses for slave operation. Format is similar to an ACL: comma, +; tab or space-separated IPv4 unicast addresses, one or more. For a slave, +; when unicast negotiation is used, setting this is mandatory. +ptpengine:unicast_destinations = + +; Specify PTP domain number for each configured unicast destination (ptpengine:unicast_destinations). +; This is only used by slave-only clocks using unicast destinations to allow for each master +; to be in a separate domain, such as with Telecom Profile. The number of entries should match the number +; of unicast destinations, otherwise unconfigured domains or domains set to 0 are set to domain configured in +; ptpengine:domain. The format is a comma, tab or space-separated list of 8-bit unsigned integers (0 .. 255) +ptpengine:unicast_domains = + +; Specify a local preference for each configured unicast destination (ptpengine:unicast_destinations). +; This is only used by slave-only clocks using unicast destinations to allow for each master's +; BMC selection to be influenced by the slave, such as with Telecom Profile. The number of entries should match the number +; of unicast destinations, otherwise unconfigured preference is set to 0 (highest). +; The format is a comma, tab or space-separated list of 8-bit unsigned integers (0 .. 255) +ptpengine:unicast_local_preference = + +; Specify peer unicast adress for P2P unicast. Mandatory when +; running unicast mode and P2P delay mode. +ptpengine:unicast_peer_destination = + +; Enable handling of PTP management messages. +ptpengine:management_enable = Y + +; Accept SET and COMMAND management messages. +ptpengine:management_set_enable = N + +; Send explicit IGMP joins between engine resets and periodically +; in master state. +ptpengine:igmp_refresh = Y + +; Periodic IGMP join interval (seconds) in master state when running +; IPv4 multicast: when set below 10 or when ptpengine:igmp_refresh +; is disabled, this setting has no effect. +ptpengine:master_igmp_refresh_interval = 60 + +; Multicast time to live for multicast PTP packets (ignored and set to 1 +; for peer to peer messages). +ptpengine:multicast_ttl = 64 + +; DiffServ CodepPoint for packet prioritisation (decimal). When set to zero, +; this option is not used. Use 46 for Expedited Forwarding (0x2e). +ptpengine:ip_dscp = 0 + +; Enable statistical filter for Sync messages. +ptpengine:sync_stat_filter_enable = N + +; Type of filter used for Sync message filtering +; Options: none mean min max absmin absmax median +ptpengine:sync_stat_filter_type = min + +; Number of samples used for the Sync statistical filter +ptpengine:sync_stat_filter_window = 4 + +; Sample window type used for Sync message statistical filter. Delay Response outlier filter action. +; Sliding window is continuous, interval passes every n-th sample only. +; Options: sliding interval +ptpengine:sync_stat_filter_window_type = sliding + +; Enable statistical filter for Delay messages. +ptpengine:delay_stat_filter_enable = N + +; Type of filter used for Delay message statistical filter +; Options: none mean min max absmin absmax median +ptpengine:delay_stat_filter_type = min + +; Number of samples used for the Delay statistical filter +ptpengine:delay_stat_filter_window = 4 + +; Sample window type used for Delay message statistical filter +; Sliding window is continuous, interval passes every n-th sample only +; Options: sliding interval +ptpengine:delay_stat_filter_window_type = sliding + +; Enable outlier filter for the Delay Response component in slave state +ptpengine:delay_outlier_filter_enable = N + +; Delay Response outlier filter action. If set to 'filter', outliers are +; replaced with moving average. +; Options: discard filter +ptpengine:delay_outlier_filter_action = discard + +; Number of samples in the Delay Response outlier filter buffer +ptpengine:delay_outlier_filter_capacity = 20 + +; Delay Response outlier filter threshold (: multiplier for Peirce's maximum +; standard deviation. When set below 1.0, filter is tighter, when set above +; 1.0, filter is looser than standard Peirce's test. +; When autotune enabled, this is the starting threshold. +ptpengine:delay_outlier_filter_threshold = 1.000000 + +; Always run the Delay Response outlier filter, even if clock is being slewed at maximum rate +ptpengine:delay_outlier_filter_always_filter = N + +; Enable automatic threshold control for Delay Response outlier filter. +ptpengine:delay_outlier_filter_autotune_enable = Y + +; Delay Response outlier filter autotune low watermark - minimum percentage +; of discarded samples in the update period before filter is tightened +; by the autotune step value. +ptpengine:delay_outlier_filter_autotune_minpercent = 20 + +; Delay Response outlier filter autotune high watermark - maximum percentage +; of discarded samples in the update period before filter is loosened +; by the autotune step value. +ptpengine:delay_outlier_filter_autotune_maxpercent = 95 + +; The value the Delay Response outlier filter threshold is increased +; or decreased by when auto-tuning. +ptpengine:delay_outlier_autotune_step = 0.100000 + +; Minimum Delay Response filter threshold value used when auto-tuning +ptpengine:delay_outlier_filter_autotune_minthreshold = 0.100000 + +; Maximum Delay Response filter threshold value used when auto-tuning +ptpengine:delay_outlier_filter_autotune_maxthreshold = 5.000000 + +; Enable Delay filter step detection (delaySM) to block when certain level exceeded +ptpengine:delay_outlier_filter_stepdetect_enable = N + +; Delay Response step detection threshold. Step detection is performed +; only when delaySM is below this threshold (nanoseconds) +ptpengine:delay_outlier_filter_stepdetect_threshold = 1000000 + +; Delay Response step level. When step detection enabled and operational, +; delaySM above this level (nanosecond) is considered a clock step and updates are paused +ptpengine:delay_outlier_filter_stepdetect_level = 500000 + +; Initial credit (number of samples) the Delay step detection filter can block for +; When credit is exhausted, filter stops blocking. Credit is gradually restored +ptpengine:delay_outlier_filter_stepdetect_credit = 200 + +; Amount of credit for the Delay step detection filter restored every full sample window +ptpengine:delay_outlier_filter_stepdetect_credit_increment = 10 + +; Delay Response outlier weight: if an outlier is detected, determines +; the amount of its deviation from mean that is used to build the standard +; deviation statistics and influence further outlier detection. +; When set to 1.0, the outlier is used as is. +ptpengine:delay_outlier_weight = 1.000000 + +; Enable outlier filter for the Sync component in slave state. +ptpengine:sync_outlier_filter_enable = N + +; Sync outlier filter action. If set to 'filter', outliers are replaced +; with moving average. +; Options: discard filter +ptpengine:sync_outlier_filter_action = discard + +; Number of samples in the Sync outlier filter buffer. +ptpengine:sync_outlier_filter_capacity = 20 + +; Sync outlier filter threshold: multiplier for the Peirce's maximum standard +; deviation. When set below 1.0, filter is tighter, when set above 1.0, +; filter is looser than standard Peirce's test. +ptpengine:sync_outlier_filter_threshold = 1.000000 + +; Always run the Sync outlier filter, even if clock is being slewed at maximum rate +ptpengine:sync_outlier_filter_always_filter = N + +; Enable automatic threshold control for Sync outlier filter. +ptpengine:sync_outlier_filter_autotune_enable = Y + +; Sync outlier filter autotune low watermark - minimum percentage +; of discarded samples in the update period before filter is tightened +; by the autotune step value. +ptpengine:sync_outlier_filter_autotune_minpercent = 20 + +; Sync outlier filter autotune high watermark - maximum percentage +; of discarded samples in the update period before filter is loosened +; by the autotune step value. +ptpengine:sync_outlier_filter_autotune_maxpercent = 95 + +; Value the Sync outlier filter threshold is increased +; or decreased by when auto-tuning. +ptpengine:sync_outlier_autotune_step = 0.100000 + +; Minimum Sync outlier filter threshold value used when auto-tuning +ptpengine:sync_outlier_filter_autotune_minthreshold = 0.100000 + +; Maximum Sync outlier filter threshold value used when auto-tuning +ptpengine:sync_outlier_filter_autotune_maxthreshold = 5.000000 + +; Enable Sync filter step detection (delayMS) to block when certain level exceeded. +ptpengine:sync_outlier_filter_stepdetect_enable = N + +; Sync step detection threshold. Step detection is performed +; only when delayMS is below this threshold (nanoseconds) +ptpengine:sync_outlier_filter_stepdetect_threshold = 1000000 + +; Sync step level. When step detection enabled and operational, +; delayMS above this level (nanosecond) is considered a clock step and updates are paused +ptpengine:sync_outlier_filter_stepdetect_level = 500000 + +; Initial credit (number of samples) the Sync step detection filter can block for. +; When credit is exhausted, filter stops blocking. Credit is gradually restored +ptpengine:sync_outlier_filter_stepdetect_credit = 200 + +; Amount of credit for the Sync step detection filter restored every full sample window +ptpengine:sync_outlier_filter_stepdetect_credit_increment = 10 + +; Sync outlier weight: if an outlier is detected, this value determines the +; amount of its deviation from mean that is used to build the standard +; deviation statistics and influence further outlier detection. +; When set to 1.0, the outlier is used as is. +ptpengine:sync_outlier_weight = 1.000000 + +; Delay between moving to slave state and enabling clock updates (seconds). +; This allows one-way delay to stabilise before starting clock updates. +; Activated when going into slave state and during slave's GM failover. +; 0 - not used. +ptpengine:calibration_delay = 0 + +; PTP idle timeout: if PTPd is in SLAVE state and there have been no clock +; updates for this amout of time, PTPd releases clock control. +; +ptpengine:idle_timeout = 120 + +; Enable panic mode: when offset from master is above 1 second, stop updating +; the clock for a period of time and then step the clock if offset remains +; above 1 second. +ptpengine:panic_mode = N + +; Duration (minutes) of the panic mode period (no clock updates) when offset +; above 1 second detected. +ptpengine:panic_mode_duration = 2 + +; When entering panic mode, release clock control while panic mode lasts +; if ntpengine:* configured, this will fail over to NTP, +; if not set, PTP will hold clock control during panic mode. +ptpengine:panic_mode_release_clock = N + +; Do not exit panic mode until offset drops below this value (nanoseconds). +; 0 = not used. +ptpengine:panic_mode_exit_threshold = 0 + +; Use PTPd's process ID as the middle part of the PTP clock ID - useful for running multiple instances. +ptpengine:pid_as_clock_identity = N + +; Fail over to NTP when PTP time sync not available - requires +; ntpengine:enabled, but does not require the rest of NTP configuration: +; will warn instead of failing over if cannot control ntpd. +ptpengine:ntp_failover = N + +; NTP failover timeout in seconds: time between PTP slave going into +; LISTENING state, and releasing clock control. 0 = fail over immediately. +ptpengine:ntp_failover_timeout = 120 + +; Prefer NTP time synchronisation. Only use PTP when NTP not available, +; could be used when NTP runs with a local GPS receiver or another reference +ptpengine:prefer_ntp = N + +; Legacy option from 2.3.0: same as ptpengine:panic_mode_release_clock +ptpengine:panic_mode_ntp = N + +; Clear counters after dumping all counter values on SIGUSR2. +ptpengine:sigusr2_clears_counters = N + +; Permit access control list for timing packets. Format is a series of +; comma, space or tab separated network prefixes: IPv4 addresses or full CIDR notation a.b.c.d/x, +; where a.b.c.d is the subnet and x is the decimal mask, or a.b.c.d/v.x.y.z where a.b.c.d is the +; subnet and v.x.y.z is the 4-octet mask. The match is performed on the source IP address of the +; incoming messages. IP access lists are only supported when using the IP transport. +ptpengine:timing_acl_permit = + +; Deny access control list for timing packets. Format is a series of +; comma, space or tab separated network prefixes: IPv4 addresses or full CIDR notation a.b.c.d/x, +; where a.b.c.d is the subnet and x is the decimal mask, or a.b.c.d/v.x.y.z where a.b.c.d is the +; subnet and v.x.y.z is the 4-octet mask. The match is performed on the source IP address of the +; incoming messages. IP access lists are only supported when using the IP transport. +ptpengine:timing_acl_deny = + +; Permit access control list for management messages. Format is a series of +; comma, space or tab separated network prefixes: IPv4 addresses or full CIDR notation a.b.c.d/x, +; where a.b.c.d is the subnet and x is the decimal mask, or a.b.c.d/v.x.y.z where a.b.c.d is the +; subnet and v.x.y.z is the 4-octet mask. The match is performed on the source IP address of the +; incoming messages. IP access lists are only supported when using the IP transport. +ptpengine:management_acl_permit = + +; Deny access control list for management messages. Format is a series of +; comma, space or tab separated network prefixes: IPv4 addresses or full CIDR notation a.b.c.d/x, +; where a.b.c.d is the subnet and x is the decimal mask, or a.b.c.d/v.x.y.z where a.b.c.d is the +; subnet and v.x.y.z is the 4-octet mask. The match is performed on the source IP address of the +; incoming messages. IP access lists are only supported when using the IP transport. +ptpengine:management_acl_deny = + +; Order in which permit and deny access lists are evaluated for timing +; packets, the evaluation process is the same as for Apache httpd. +; Options: permit-deny deny-permit +ptpengine:timing_acl_order = deny-permit + +; Order in which permit and deny access lists are evaluated for management +; messages, the evaluation process is the same as for Apache httpd. +; Options: permit-deny deny-permit +ptpengine:management_acl_order = deny-permit + +; Do not adjust the clock +clock:no_adjust = Y + +; Do not step the clock - only slew +clock:no_reset = N + +; Force clock step on first sync after startup regardless of offset and clock:no_reset +clock:step_startup_force = N + +; Step clock on startup if offset >= 1 second, ignoring +; panic mode and clock:no_reset +clock:step_startup = N + +; Attempt setting the RTC when stepping clock (Linux only - FreeBSD does +; this for us. WARNING: this will always set the RTC to OS clock time, +; regardless of time zones, so this assumes that RTC runs in UTC or +; at least in the same timescale as PTP. true at least on most +; single-boot x86 Linux systems. +clock:set_rtc_on_step = N + +; Observed drift handling method between servo restarts: +; reset: set to zero (not recommended) +; preserve: use kernel value, +; file: load/save to drift file on startup/shutdown, use kernel +; value inbetween. To specify drift file, use the clock:drift_file setting. +; Options: reset preserve file +clock:drift_handling = preserve + +; Specify drift file +clock:drift_file = /etc/ptpd_kernelclock.drift + +; Time (seconds) before and after midnight that clock updates should pe suspended for +; during a leap second event. The total duration of the pause is twice +; the configured duration +clock:leap_second_pause_period = 5 + +; Time (seconds) before midnight that PTPd starts announcing the leap second +; if it's running as master +clock:leap_second_notice_period = 43200 + +; Specify leap second file location - up to date version can be downloaded from +; http://www.ietf.org/timezones/data/leap-seconds.list +clock:leap_seconds_file = + +; Behaviour during a leap second event: +; accept: inform the OS kernel of the event +; ignore: do nothing - ends up with a 1-second offset which is then slewed +; step: similar to ignore, but steps the clock immediately after the leap second event +; smear: do not inform kernel, gradually introduce the leap second before the event +; by modifying clock offset (see clock:leap_second_smear_period) +; Options: accept ignore step smear +clock:leap_second_handling = accept + +; Time period (Seconds) over which the leap second is introduced before the event. +; Example: when set to 86400 (24 hours), an extra 11.5 microseconds is added every second +clock:leap_second_smear_period = 86400 + +; Maximum absolute frequency shift which can be applied to the clock servo +; when slewing the clock. Expressed in parts per million (1 ppm = shift of +; 1 us per second. Values above 512 will use the tick duration correction +; to allow even faster slewing. Default maximum is 512 without using tick. +clock:max_offset_ppm = 500 + +; One-way delay filter stiffness. +servo:delayfilter_stiffness = 6 + +; Clock servo PI controller proportional component gain (kP). +servo:kp = 0.100000 + +; Clock servo PI controller integral component gain (kI). +servo:ki = 0.001000 + +; How servo update interval (delta t) is calculated: +; none: servo not corrected for update interval (dt always 1), +; constant: constant value (target servo update rate - sync interval for PTP, +; measured: servo measures how often it's updated and uses this interval. +; Options: none constant measured +servo:dt_method = constant + +; Maximum servo update interval (delta t) when using measured servo update interval +; (servo:dt_method = measured), specified as sync interval multiplier. +servo:dt_max = 5.000000 + +; Enable clock synchronisation servo stability detection +; (based on standard deviation of the observed drift value) +; - drift will be saved to drift file / cached when considered stable, +; also clock stability status will be logged. +servo:stability_detection = N + +; Specify the observed drift standard deviation threshold in parts per +; billion (ppb) - if stanard deviation is within the threshold, servo +; is considered stable. +servo:stability_threshold = 10.000000 + +; Specify for how many statistics update intervals the observed drift +; standard deviation has to stay within threshold to be considered stable. +servo:stability_period = 1 + +; Specify after how many minutes without stabilisation servo is considered +; unstable. Assists with logging servo stability information and +; allows to preserve observed drift if servo cannot stabilise. +; +servo:stability_timeout = 10 + +; Do accept master to slave delay (delayMS - from Sync message) or slave to master delay +; (delaySM - from Delay messages) if greater than this value (nanoseconds). 0 = not used. +servo:max_delay = 0 + +; Maximum number of consecutive delay measurements exceeding maxDelay threshold, +; before slave is reset. +servo:max_delay_max_rejected = 0 + +; If servo:max_delay is set, perform the check only if clock servo has stabilised. +; +servo:max_delay_stable_only = N + +; When enabled, Sync messages will only be accepted if sequence ID is increasing. This is limited to 50 dropped messages. +; +ptpengine:sync_sequence_checking = N + +; If set to non-zero, timeout in seconds, after which the slave resets if no clock updates made. +; +ptpengine:clock_update_timeout = 0 + +; Do not reset the clock if offset from master is greater +; than this value (nanoseconds). 0 = not used. +servo:max_offset = 0 + +; Enable SNMP agent (if compiled with PTPD_SNMP). +;global:enable_snmp = N + +; Send log messages to syslog. Disabling this +; sends all messages to stdout (or speficied log file). +global:use_syslog = Y + +; Lock file location +global:lock_file = + +; Use mode specific and interface specific lock file +; (overrides global:lock_file). +global:auto_lockfile = N + +; Lock file directory: used with automatic mode-specific lock files, +; also used when no lock file is specified. When lock file +; is specified, it's expected to be an absolute path. +global:lock_directory = /var/run + +; Skip lock file checking and locking. +global:ignore_lock = N + +; File used to record data about sync packets. Enables recording when set. +global:quality_file = + +; Maximum sync packet record file size (in kB) - file will be truncated +; if size exceeds the limit. 0 - no limit. +global:quality_file_max_size = 0 + +; Enable log rotation of the sync packet record file up to n files. +; 0 - do not rotate. +; +global:quality_file_max_files = 0 + +; Truncate the sync packet record file every time it is (re) opened: +; startup and SIGHUP. +global:quality_file_truncate = N + +; File used to log ptpd status information. +global:status_file = /var/run/ptpd.status + +; Enable / disable writing status information to file. +global:log_status = Y + +; Status file update interval in seconds. +global:status_update_interval = 1 + +; Specify log file path (event log). Setting this enables logging to file. +global:log_file = + +; Maximum log file size (in kB) - log file will be truncated if size exceeds +; the limit. 0 - no limit. +global:log_file_max_size = 0 + +; Enable log rotation of the sync packet record file up to n files. +; 0 - do not rotate. +; +global:log_file_max_files = 0 + +; Truncate the log file every time it is (re) opened: startup and SIGHUP. +global:log_file_truncate = N + +; Specify log level (only messages at this priority or higer will be logged). +; The minimal level is LOG_ERR. LOG_ALL enables debug output if compiled with +; RUNTIME_DEBUG. +; Options: LOG_ERR LOG_WARNING LOG_NOTICE LOG_INFO LOG_ALL +global:log_level = LOG_ALL + +; Specify statistics log file path. Setting this enables logging of +; statistics, but can be overriden with global:log_statistics. +global:statistics_file = + +; Log timing statistics every n seconds for Sync and Delay messages +; (0 - log all). +global:statistics_log_interval = 0 + +; Maximum statistics log file size (in kB) - log file will be truncated +; if size exceeds the limit. 0 - no limit. +global:statistics_file_max_size = 0 + +; Enable log rotation of the statistics file up to n files. 0 - do not rotate. +global:statistics_file_max_files = 0 + +; Truncate the statistics file every time it is (re) opened: startup and SIGHUP. +global:statistics_file_truncate = N + +; Dump the contents of every PTP packet +global:dump_packets = N + +; Run in foreground with statistics and all messages logged to stdout. +; Overrides log file and statistics file settings and disables syslog. +; +global:verbose_foreground = N + +; Run in foreground - ignored when global:verbose_foreground is set +global:foreground = N + +; Log timing statistics for every PTP packet received +; +global:log_statistics = N + +; Timestamp format used when logging timing statistics +; (when global:log_statistics is enabled): +; datetime - formatttted date and time: YYYY-MM-DD hh:mm:ss.uuuuuu +; unix - Unix timestamp with nanoseconds: s.ns +; both - Formatted date and time, followed by unix timestamp +; (adds one extra field to the log) +; +; Options: datetime unix both +global:statistics_timestamp_format = datetime + +; Bind ptpd process to a selected CPU core number. +; 0 = first CPU core, etc. -1 = do not bind to a single core. +global:cpuaffinity_cpucore = 0 + +; Clock synchronisation statistics update interval in seconds +; +global:statistics_update_interval = 30 + +; Log a status update every time statistics are updated (global:statistics_update_interval). +; The updates are logged even when ptpd is configured without statistics support +global:periodic_updates = N + +; Delay (seconds) before releasing a time service (NTP or PTP) and electing a new one to control a clock. 0 = elect immediately +; +global:timingdomain_election_delay = 15 + +; Enable NTPd integration +ntpengine:enabled = N + +; Enable control over local NTPd daemon +ntpengine:control_enabled = N + +; NTP control check interval in seconds +; +ntpengine:check_interval = 15 + +; NTP key number - must be configured as a trusted control key in ntp.conf, +; and be non-zero for the ntpengine:control_enabled setting to take effect. +; +ntpengine:key_id = 0 + +; NTP key (plain text, max. 20 characters) - must match the key configured in +; ntpd's keys file, and must be non-zero for the ntpengine:control_enabled +; setting to take effect. +; +ntpengine:key = + +; ========= newline required in the end ========== + From 7be6df40e7b80acbc31ac568f902533906cee600 Mon Sep 17 00:00:00 2001 From: Mike Purvis Date: Fri, 30 May 2025 19:21:17 -0400 Subject: [PATCH 4/5] Add changelog entry --- debian/changelog | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/debian/changelog b/debian/changelog index e0ab4e2e..651b21af 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +ptpd (2.3.1-debian1-4build2-simbe0) noble; urgency=medium + + * Bring in upstream source as of 1ec9e65 + * Add in systemd unit + * simbe-specific conffile in /etc/ptpd.conf + + -- Mike Purvis Fri, 30 May 2025 19:18:15 -0400 + ptpd (2.3.1-debian1-4build2) noble; urgency=medium * No-change rebuild for CVE-2024-3094 From d74a4ccc49dc1eed83addbb3109b0d996270e119 Mon Sep 17 00:00:00 2001 From: Mike Purvis Date: Fri, 30 May 2025 19:27:17 -0400 Subject: [PATCH 5/5] Fix pipeline --- .github/workflows/build.yaml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 46149b66..b025f109 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -1,8 +1,7 @@ #------------------------------------------------------------------------------ -# .github/workflows/pure.yaml +# .github/workflows/build.yaml #------------------------------------------------------------------------------ -# Workflow that builds tally-pure. There's no need to build this for multiple -# arches since it's just textual scripts. +# Build simbe's forked ptpd deb package and upload to gemfury on tags. #------------------------------------------------------------------------------ # Authors: Mike Purvis # Copyright (c) 2025, Simbe Robotics, Inc. @@ -43,4 +42,4 @@ jobs: exit 1 fi - #curl -F package=@$(ls ../ptpd_*.deb) https://${{ secrets.GEMFURY_API_KEY }}@push.fury.io/simberobotics + curl -F package=@$(ls ../ptpd_*.deb) https://${{ secrets.GEMFURY_API_KEY }}@push.fury.io/simberobotics