nqptp
is a daemon that monitors timing data from PTP clocks it sees on ports 319 and 320. It maintains records for one clock, identified by its Clock ID.
It is a companion application to Shairport Sync and provides timing information for AirPlay 2 operation.
This guide is for recent Linux and FreeBSD systems.
As usual, you should first ensure everything is up to date.
As you probably know, you can download the repository in two ways: (1) using git
to clone it -- recommended -- or (2) downloading the repository as a ZIP archive. Please use the git
method. The reason it that when you use git
,
the build process can incorporate the git
build information in the version string you get when you execute the command $ nqptp -V
.
This will be very useful for identifying the exact build if you are making comments or bug reports. Here is an example:
Version with git build information:
Version: 1.1-dev-24-g0c00a79. Shared Memory Interface Version: 5.
Version without git build information:
Version: 1.1-dev. Shared Memory Interface Version: 5.
If you are updating from version 1.2.4
or earlier in Linux, remove the service file nqptp.service
from the directories /lib/systemd/system
and /usr/local/lib/systemd/system
(you'll need superuser privileges):
# rm /lib/systemd/system/nqptp.service
# rm /usr/local/lib/systemd/system/nqptp.service
# systemctl daemon-reload
Don't worry if you get a message stating that the files doesn't exist -- no harm done.
At present, there is no need to remove the old startup script as (in FreeBSD only) it is always replaced during the # make install
step.
The startup script is at /usr/local/etc/rc.d/nqptp
.
Note that you will need superuser privileges to install, enable and start the daemon.
$ git clone https://github.com/mikebrady/nqptp.git
$ cd nqptp
$ autoreconf -fi
$ ./configure --with-systemd-startup
$ make
# make install
$ git clone https://github.com/mikebrady/nqptp.git
$ cd nqptp
$ autoreconf -fi
$ ./configure --with-freebsd-startup
$ make
# make install
The make install
installs a startup script as requested. You should enable it and start it in the normal way:
If you are installing nqptp
for the first time, enable it and start it:
# systemctl enable nqptp
# systemctl start nqptp
If Shairport Sync is already running, you should restart it after starting nqptp
:
# systemctl restart shairport-sync
If you are updating an existing installation of nqptp
, after installing it you should restart it. You should then also restart Shairport Sync:
# systemctl restart nqptp
# systemctl restart shairport-sync
If you are installing nqptp
for the first time, add an automatic startup entry for it in /etc/rc.local
and start it:
- Edit
/etc/rc.conf
and add the following line:nqptp_enable="YES"
- When you have finished editing
/etc/rc.conf
, you can startnqptp
from the command line:# service nqptp start
If Shairport Sync is already running, you should you restart it after starting nqptp
:
# service shairport_sync restart
If you are updating an existing installation of nqptp
, after installing it you should restart it. You should then also restart Shairport Sync:
# service nqptp restart
# service shairport_sync restart
If your system runs a firewall, ensure that ports 319 and 320 are open for UDP traffic in both directions. These ports are associated with PTP service and may be referred to as "PTP" in firewall rules. For example, the following would open ports 319 and 320 for Fedora, which uses firewalld
:
# firewall-cmd --add-service=ptp
# firewall-cmd --permanent --add-service=ptp # make it permanent across reboots
The nqptp
application requires exclusive access to ports 319 and 320.
This means that it can not coexist with any other user of those ports, such as full PTP service daemons.
In Linux, nqptp
runs as a low-priviliged user but is given special access to ports 319 and 320 using systemd AmbientCapabilities
.
In FreeBSD, nqptp
runs as root
user.
Commands and status information are sent to nqptp
over port 9000.
Information about the PTP clock is provided via a POSIX shared memory interface.
Here are details of the interface:
typedef struct {
uint64_t master_clock_id; // the current master clock
uint64_t local_time; // the time when the offset was calculated
uint64_t local_to_master_time_offset; // add this to the local time to get master clock time
uint64_t master_clock_start_time; // this is when the master clock became master
} shm_structure_set;
// The actual interface comprises a shared memory region of type struct shm_structure.
// This comprises two records of type shm_structure_set.
// The secondary record is written strictly after all writes to the main record are
// complete. This is ensured using the __sync_synchronize() construct.
// The reader should ensure that both copies match for a read to be valid.
// For safety, the secondary record should be read strictly after the first.
struct shm_structure {
uint16_t version; // check this is equal to NQPTP_SHM_STRUCTURES_VERSION
shm_structure_set main;
shm_structure_set secondary;
};
Clock records that are not updated for a period are deleted.
nqptp
has not been thoroughly checked or audited for security issues. Note that it runs inroot
mode on FreeBSD.- It's probably buggy!
nqptp
does not take advantage of hardware timestamping.
The nqptp
daemon is under active development and, consequently, everything here can change, possibly very radically.
nqptp
uses just a part of the IEEE 1588-2008 protocol. It is not a PTP clock.