Go packages

The Go packages can be divided up into layers, where packages in each layer depend on only packages in the same and lower layers.

Command-line layer

Provides the user interface to the programs, including the command-line interface and the configuration file.

cmd/satpulsetool provides main for satpulsetool.

cmd/satpulsed provides main for satpulsed.

internal/daemon implements the satpulsed daemon. It orchestrates all the parts of the satpulsed program. It also handles the TOML config file.

internal/pmccmd implements pmc subcommand of satpulsetool.

internal/gpscmd implements gps command of satpulsetool.

cmd/ifwait provides a program that waits for a network interface to become ready. It exercises the functionality of the internal/ifwait package.

internal/cmd provides some common functionality used for command-line interfaces.

Application layer

Provides the main blocks of the applications.

internal/gpsio implements a goroutine that reads input from the GPS, splits it into packets and sends those packets to a channel. It provides an abstraction for performing IO on a GPS, which can work either over a serial connection (using term) or over a network connection. The input is split into packets using the internal/scan package.

internal/gpscfg drives the GPS configuration process. It combines internal/gpsio and internal/gpsprot.

internal/ts implements a goroutine that reads external timestamps from the PTP hardware clock and sends those to a channel. These external timestamps are the time pulses emitted by the GPS receiver.

internal/gpsevent provides the main event handling loop after GPS configuration is done. It receives GPS packets from internal/gpsio and then uses the appropriate protocol implementation to construct a protocol-independent messages that it passes to internal/combine and internal/mon. It also receives timestamps from internal/ts and passes them to `internal/combine.

internal/combine is called by internal/gpsevent with events for time pulses and with events for GPS messages giving the current time. It generates samples that combine the PHC time of a time pulse with the correct time of that time pulse in the PTP timescale. It then passes these samples to internal/mon.

internal/mon is called by internal/combine and internal/gpsevent. It removes outliers from the samples it receives before passing them to internal/servo. It monitors the synchronization status and reports it to the PTP grandmaster using internal/pmc. It also sends samples to chrony using internal/sockrefclock.

internal/servo is called by internal/mon. It uses the samples it receives to drive a Proportional-Integral servo that adjusts the frequency of the PHC to bring it into phase with the GPS time pulses.

internal/proxy implements proxying of GPS packets to TCP and Unix domain sockets.

web embeds the HTML/JavaScript code for the web interface. This code is transpiled from TypeScript and uses Preact JavaScript library.

internal/bcast concurrency abstraction broadcasts a channel to multiple other channels.

internal/logfile provides utility functions for opening and reopening log files.

Domain layer

Provides packages using domain-specific abstractions that are used by the application layer. These packages have mutual dependencies. They do not make use of goroutines nor do they perform no logging.

internal/ptime provides a Time type that represents time in the PTP timescale (nanoseconds in TAI timescale since 1970-01-01T00:00:00 TAI). This is used throught the domain layer and higher level layers.

internal/scan provides a Packet type representing a packet of GPS data in some protocol. It also provides a scan function to split up a stream of bytes into packets. It does not interpret the content of the packet.

internal/gpsprot abstracts a GPS protocol such as UBX or NMEA. This operates in two phases: configuration and post-configuration. The post-configuration part of this defines types that represent the information contained in GPS messages in a protovo

internal/ubx implements internal/gpsprot abstractions for the UBX protocol. It uses internal/ubx/bin and internal/ubxcfgval to do this.

internal/nmea implements internal/gpsprot abstractions for the NMEA protocol.

internal/phc provides low level abstractions to access the PTP hardware clock. It is highly Linux dependent. It uses internal/ptime.

internal/sockrefclock implements the chrony refclock protocol. It uses internal/ptime.

Library layer

Provides a library of packages, which are potentially useful outside satpulse. There are no mutual dependencies. These packages do not make use of goroutines nor do they perform no logging.

internal/ubx/bin translates binary packets in the UBX protocol to and from Go structs.

internal/ubxcfgval handles the 9th generation UBX format for configuration data that is payload for UBX-CFG-VALGET/VALSET messages

internal/ubxcfgval/cfgschema contains a YAML schema for configuration data handled by internal/ubxcfgval. This is used to generate code in the internal/ubxcfgval package.

internal/ifwait use the Linux kernel’s netlink subsystem to wait for changes in a network interface’s status.

internal/devnotify uses the Linux kernel’s netlink subsystem to listen for creation of new devices by udev. (This is not used currently.)

internal/pmc implements a PTP management client.

internal/sse marshals data into the format of HTML SSE (server-sent events).

internal/allan computes Allan deviations. (This is not used currently.)

internal/geopos converts between positions in the ECEF and LLA geodetic coordinate systems. This is used by the web interface to link to Google makes.

term provides access to the Linux terminal interface, which provides access to serial devices. This is similar to github.com/pkg/term, but provides additional Linux-specific functionality.