NTP under OpenBSD 5.0

This is my saga of getting NTP to work under OpenBSD 5.0. The "real" NTP, traceable to Dr. David L. Mills, not whatever OpenBSD's pawning off as its built-in ntpd. That won't get the time via audio from a radio so I have no interest in it, and they don't plan to add audio clocks. Rename /usr/sbin/ntpd so you don't get confused. This comes from ntp.org

So yes, this is another "how I did it" page, which isn't necessarily how you should do it. Back sometime around 1992 I started fiddling with trying to correct drift in my computer's clock. The program was probably written in Turbo Pascal and under DOS. You had to have a shortwave tuned to WWV or CHU and you'd preset the time of the next clock beep, then hit enter at a special prompt when the beep happened. So it was subject to reaction time, but it was accurate enough that I could see the effect of room temperature changes. It stored a drift rate then every time you booted another program would adjust the clock time based on how long since it had been run and the calculated drift. Then I went back to college at the end of the summer and forgot about it.

A few years ago I ran into a program called just chu.c which I think came with a FreeBSD version I was running at the time. It looked interesting but I never got it to work. Gradually I became aware that ntp.org's ntpd could accept audio input from a radio and set time within 1 millisecond over hf radio/audio so I grabbed a copy and tried to get it running a few years ago, but couldn't and lost interest.

So now, May 2012, I'm retired with time to burn, better programming skills, and mostly OpenBSD based, so I tried again. And at this point I'm getting there. OpenBSD is an operating system that doesn't have a huge user base like Linux or even FreeBSD, so they don't have a lot of clout. Lots of people have never heard of it and even less care anything about it. Having fought viruses for 17 years at 2 jobs with Windows I can appreciate that OpenBSD has probably the best security record of any operating system. They try to be humble about it, but it's been over 10 years since anyone or anything has broken into an OpenBSD machine from outside. And both of those were outside programs (ftp and x) that they include in their distribution. Both holes also affected Linux, FreeBSD and just about everything else.

This is not meant to be an exhaustive set of NTP documentation by any means. If you get the distribution from ntp.org it has 91 html files in it describing how to set it up and run it. The program's huge though, with something like 380 individual C files (these counts are by using Midnight Commander on ntp-4.2.6p5). I'm just beginning to be able to find my way around, both in the documentation and the code.

This computer triple boots into OpenBSD, Debian Linux and Windows XP. I had no trouble at all installing NTP under Linux, but I don't use that much. I haven't tried installing under Windows since that gets used maybe once a month. Having NTP running under Linux gave me something to compare the OpenBSD against, and I copied my working ntp.conf file from Linux to OpenBSD. Of course they're both running the same hardware so that was handy too.

I started by comparing audioctl's idea of my sound settings.

5/10/2011
I got all the settings right according to audioctl, except I can't set record.active=1 from within ntpd/audio.c, at least yet. I think that's because active belongs to 1 of 2 struct audio_prinfos which fit into a struct audio_info. ntpd/audio.c has no mention of a struct audio_prinfo. For now I can get ntpd running then set record.active with audioctl. When I do that ntpd starts accumulating clockstats and it looks like it's working. See the tarball of headers that I put here to see how the structs are set up.

Except that the radio stays on noisy WWV frequencies as long as it stays on the good frequencies. It should pick a good one and mostly stay there, just visiting the others for a few seconds once in a while to check propagation.

So I finally put a crude routine into ntpd/refclock_wwv.c which dumps some audio data out to a file so I can look at it. It's all zeroes. I fiddled around in NTP for a while, then wrote a little standalone program that just opens the sound device, grabs 8000 bytes of data (1 second worth), writes it to a file, and quits. That gets all zeroes too.

5/11/2012
Before I booted up for the day I stuck in a different soundcard instead of using motherboard sound. There's mention in the man page for the motherboard sound driver that some hardware can only run at a fixed sampling rate. Mine runs at 48000 and there are routines in ntpd/refclock_wwv.c which require 8000 because they base timing on number of samples. Fldigi can work at different sample rates but that uses libsamplerate so it can resample the incoming audio when it needs to. I don't have many working programs which capture audio to study, and even Fldigi works through a PortAudio layer so it's not that useful. gpsk31 might work.

I've always heard that OpenBSD sound was weird, so I'm looking into why. It has some mention in various places of being partly derived from Sun audio. I've heard from somewhre that OpenBSD's native sound is called "sndio" and I've bantered that term around in various discussions but it didn't occur to me until I did "locate sndio" that there's actually a sndio manpage

But I'm still not sure that sndio is what I want. It's distributed with OpenBSD, the sources are right there in the same source tarball as the rest of the system, but is it "native" enough? I'm torn between wanting to get to the bottom of this, what OpenBSD sound is like at the most basic level without any add-ons which would cause dependancies, and just making it work with NTP. There's no sio_* stuff in NTP that I've seen. That's only present in OpenBSD and maybe NetBSD.

NTP's understanding of this is limited to knowing about sys/audioio.h and mainly the audio_info struct. There are links from the sndio manpages to audio which is the layer where audio_info is, but audio_info isn't part of sndio from what I can tell. I see at the bottom of the audio.9 manpage that "audio" has been part of OpenBSD since OpenBSD 1.2. That sounds like what I'm looking for. Hardly a name to be dropping like Alsa, but oh well. The audio.9 manpage goes into the links between the hardware at the lower end and on up to the level I'm used to where NTP might connect to it.

So OpenBSD's native sound is called just "audio" which is possibly a little hard to explain. sndio comes with OpenBSD and coexists with audio, but it's independent. There's also an OSS layer for compatibility with Linux but it's not fully implemented. The most portable layer which is an add-on in the ports collection is PortAudio, which is itself a little shaky and I think has been abandoned by its author. It's through PortAudio that Audacity and Fldigi work. Well, it's like Linux has Alsa and OSS before that, maybe 1 or 2 others over time, and I think FreeBSD has about 3 different sound systems too.

Now I can go into the kernel source and find the driver for my sound card and follow the chain from a struct audio_hw on that end to the struct audio_info that NTP sees. I feel better, but nothing's working yet. At least I'm looking at the right layer.

My earlier concerns about being able to write into a struct audio_prinfo when only the parent struct audio_info was declared in the program were unfounded. That's the way C is supposed to work. I'm more used to Pascal/Delphi but not so much lately. I wish the world was written in Pascal, not C, but oh well. Think of all that strong typing in action: no more buffer overflows.

5/12/2012 digging into audioctl

5/13/2012 another frustrating day.

5/24/2012 I've got William Rossi's chu program working

This page isn't finished yet...

AB1JX / toys