79 lines
3.5 KiB
C
79 lines
3.5 KiB
C
/*
|
|
* This file is part of the nqptp distribution (https://github.com/mikebrady/nqptp).
|
|
* Copyright (c) 2021--2023 Mike Brady.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, version 2.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
* Commercial licensing is also available.
|
|
*/
|
|
|
|
#ifndef NQPTP_SHM_STRUCTURES_H
|
|
#define NQPTP_SHM_STRUCTURES_H
|
|
|
|
#define NQPTP_INTERFACE_NAME "/nqptp"
|
|
|
|
#define NQPTP_SHM_STRUCTURES_VERSION 10
|
|
#define NQPTP_CONTROL_PORT 9000
|
|
|
|
// The control port expects a UDP packet with the first character being a command letter
|
|
// and the rest being any arguments, the whole not to exceed 4096 characters.
|
|
// The "T" command, must followed by nothing or by
|
|
// a space and a space-delimited list of IPv4 or IPv6 numbers.
|
|
// The IPs, if provided, will become the new list of timing peers, replacing any
|
|
// previous list. The first IP number is the clock that NQPTP will listen to.
|
|
// The remaining IP address are the addresses of all the timing peers. The timing peers
|
|
// are not used in this version of NQPTP.
|
|
// If no timing list is provided, the existing timing list is deleted.
|
|
// The "B" command is a message that the client -- which generates the clock --
|
|
// is about to start playing.
|
|
// NQPTP uses it to determine that the clock is active and will not sleep.
|
|
// The "E" command signifies that the client has stopped playing and that
|
|
// the clock may shortly sleep.
|
|
// The "P" command signifies that SPS has paused play (buffered audio only).
|
|
// The clock seems to stay running in this state.
|
|
|
|
// When the clock is active, it is assumed that any decreases in the offset
|
|
// between the local and remote clocks are due to delays in the network.
|
|
// NQPTP smooths the offset by clamping any decreases to a small value.
|
|
// In this way, it can follow clock drift but ignore network delays.
|
|
|
|
// When the clock is inactive, it can stop running. This causes the offset to decrease.
|
|
// NQPTP clock smoothing would treat this as a network delay, causing true sync to be lost.
|
|
// To avoid this, when the clock goes from inactive to active,
|
|
// NQPTP resets clock smoothing to the new offset.
|
|
|
|
#include <inttypes.h>
|
|
#include <pthread.h>
|
|
|
|
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;
|
|
};
|
|
|
|
#endif
|