summaryrefslogtreecommitdiffstats
path: root/contrib/ntp/ntpd/refclock_oncore.c
diff options
context:
space:
mode:
authorroberto <roberto@FreeBSD.org>2000-01-28 14:55:50 +0000
committerroberto <roberto@FreeBSD.org>2000-01-28 14:55:50 +0000
commitb5b40f9e420899251189775800d9f74092925299 (patch)
tree98efdf1b74d6ecb7828bb502a0350116eeb2fd3c /contrib/ntp/ntpd/refclock_oncore.c
parentef64b99e8412f2273dd2e8b3291c2f78ffc4667f (diff)
downloadFreeBSD-src-b5b40f9e420899251189775800d9f74092925299.zip
FreeBSD-src-b5b40f9e420899251189775800d9f74092925299.tar.gz
Virgin import of ntpd 4.0.99b
Diffstat (limited to 'contrib/ntp/ntpd/refclock_oncore.c')
-rw-r--r--contrib/ntp/ntpd/refclock_oncore.c561
1 files changed, 389 insertions, 172 deletions
diff --git a/contrib/ntp/ntpd/refclock_oncore.c b/contrib/ntp/ntpd/refclock_oncore.c
index 9ff3d23..e0ba177 100644
--- a/contrib/ntp/ntpd/refclock_oncore.c
+++ b/contrib/ntp/ntpd/refclock_oncore.c
@@ -55,6 +55,13 @@
#define POS_HOLD_AVERAGE 10000 /* nb, 10000s ~= 2h45m */
+/*
+ * ONCORE_SHMEM_STATUS will create a mmap(2)'ed file named according to a
+ * "STATUS" line in the oncore config file, which contains the most recent
+ * copy of all types of messages we recognize. This file can be mmap(2)'ed
+ * by monitoring and statistics programs.
+ */
+
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@@ -66,6 +73,14 @@
#include <sys/types.h>
#include <sys/time.h>
#include <sys/stat.h>
+#ifdef ONCORE_SHMEM_STATUS
+# ifdef HAVE_SYS_MMAN_H
+# include <sys/mman.h>
+# ifndef MAP_FAILED
+# define MAP_FAILED ((u_char *) -1)
+# endif /* not MAP_FAILED */
+# endif /* HAVE_SYS_MMAN_H */
+#endif /* ONCORE_SHMEM_STATUS */
#ifdef HAVE_PPSAPI
# ifdef HAVE_TIMEPPS_H
@@ -77,6 +92,10 @@
# endif
#endif
+#ifdef HAVE_SYS_SIO_H
+# include <sys/sio.h>
+#endif
+
#include "ntpd.h"
#include "ntp_io.h"
#include "ntp_unixtime.h"
@@ -122,6 +141,8 @@ struct instance {
int unit; /* 127.127.30.unit */
int ttyfd; /* TTY file descriptor */
int ppsfd; /* PPS file descriptor */
+ int statusfd; /* Status shm descriptor */
+ u_char *shmem;
#ifdef HAVE_PPSAPI
pps_handle_t pps_h;
pps_params_t pps_p;
@@ -134,7 +155,6 @@ struct instance {
struct peer *peer;
int Bj_day;
- int assert;
long delay; /* ns */
long offset; /* ns */
@@ -144,11 +164,11 @@ struct instance {
double ss_ht;
int ss_count;
u_char ss_ht_type;
- int posn_set;
+ u_char posn_set;
- int printed;
+ u_char printed;
+ u_char polled;
int pollcnt;
- int polled;
u_int ev_serial;
int Rcvptr;
u_char Rcvbuf[500];
@@ -160,6 +180,8 @@ struct instance {
u_char Az;
u_char init_type;
s_char saw_tooth;
+ u_char timeout; /* flag to retry Cj after Fa reset */
+ s_char assert;
};
#define rcvbuf instance->Rcvbuf
@@ -172,7 +194,6 @@ static void oncore_receive P((struct recvbuf *));
static void oncore_sendmsg P((int fd, u_char *, u_int));
static void oncore_shutdown P((int, struct peer *));
static int oncore_start P((int, struct peer *));
-static void oncore_stats P((struct instance *));
static void oncore_msg_any P((struct instance *, u_char *, u_int, int));
static void oncore_msg_As P((struct instance *, u_char *, u_int));
@@ -180,6 +201,7 @@ static void oncore_msg_At P((struct instance *, u_char *, u_int));
static void oncore_msg_Ay P((struct instance *, u_char *, u_int));
static void oncore_msg_Az P((struct instance *, u_char *, u_int));
static void oncore_msg_Bj P((struct instance *, u_char *, u_int));
+static void oncore_msg_Cb P((struct instance *, u_char *, u_int));
static void oncore_msg_Cf P((struct instance *, u_char *, u_int));
static void oncore_msg_Cj P((struct instance *, u_char *, u_int));
static void oncore_msg_Ea P((struct instance *, u_char *, u_int));
@@ -201,11 +223,12 @@ struct refclock refclock_oncore = {
* for the the UT or VP Oncore.
*/
-static struct {
+static struct msg_desc {
const char flag[3];
const int len;
void (*handler) P((struct instance *, u_char *, u_int));
const char *fmt;
+ int shmem;
} oncore_messages[] = {
/* Ea and En first since they're most common */
{ "Ea", 76, oncore_msg_Ea, "mdyyhmsffffaaaaoooohhhhmmmmvvhhddtntimsdimsdimsdimsdimsdimsdimsdimsdsC" },
@@ -223,7 +246,7 @@ static struct {
{ "AB", 8, 0, "" },
{ "Bb", 92, 0, "" },
{ "Bj", 8, oncore_msg_Bj, "" },
- { "Cb", 33, 0, "" },
+ { "Cb", 33, oncore_msg_Cb, "" },
{ "Cf", 7, oncore_msg_Cf, "" },
{ "Cg", 8, 0, "" },
{ "Ch", 9, 0, "" },
@@ -234,6 +257,7 @@ static struct {
{ {0}, 7, 0, ""}
};
+static unsigned int oncore_shmem_Cb;
/*
* Position Set.
@@ -262,6 +286,11 @@ u_char oncore_cmd_Asx[]= { 'A', 's', 0x7f, 0xff, 0xff, 0xff,
u_char oncore_cmd_Aw[] = { 'A', 'w', 1 };
/*
+ * Output Almanac when it changes
+ */
+u_char oncore_cmd_Be[] = { 'B', 'e', 1 };
+
+/*
* Read back PPS Offset for Output
*/
u_char oncore_cmd_Ay[] = { 'A', 'y', 0, 0, 0, 0 };
@@ -281,7 +310,7 @@ u_char oncore_cmd_AB[] = { 'A', 'B', 4 };
/*
* Visible Satellite Status Msg.
*/
-u_char oncore_cmd_Bb[] = { 'B', 'b', 0 }; /* just turn off */
+u_char oncore_cmd_Bb[] = { 'B', 'b', 1 };
/*
* Leap Second Pending Message
@@ -357,6 +386,10 @@ static u_char oncore_cmd_Fa[] = { 'F', 'a' };
/* from buffer, char *buf, result to an int */
#define buf_w32(buf) (((buf)[0]&0200) ? (-(~w32(buf)+1)) : w32(buf))
+extern int pps_assert;
+extern int pps_hardpps;
+
+
/*
* oncore_start - initialize data for processing
*/
@@ -400,8 +433,7 @@ oncore_start(
if ((stat1.st_dev == stat2.st_dev) && (stat1.st_ino == stat2.st_ino)) {
/* same device here */
if (!(fd1 = refclock_open(device1, SPEED, LDISC_RAW
-#ifdef HAVE_PPSAPI
-#else
+#if !defined(HAVE_PPSAPI) && !defined(TIOCDCDTIMESTAMP)
| LDISC_PPS
#endif
))) {
@@ -435,7 +467,7 @@ oncore_start(
instance->ppsfd = fd2;
instance->Bj_day = -1;
- instance->assert = 1;
+ instance->assert = pps_assert;
/* go read any input data in /etc/ntp.oncoreX */
@@ -444,10 +476,26 @@ oncore_start(
#ifdef HAVE_PPSAPI
if (time_pps_create(fd2, &instance->pps_h) < 0) {
perror("time_pps_create");
- exit(1);
+ return(0);
}
- if (instance->assert) {
+ if (time_pps_getcap(instance->pps_h, &mode) < 0) {
+ msyslog(LOG_ERR,
+ "refclock_ioctl: time_pps_getcap failed: %m");
+ return (0);
+ }
+
+ if (time_pps_getparams(instance->pps_h, &instance->pps_p) < 0) {
+ msyslog(LOG_ERR,
+ "refclock_ioctl: time_pps_getparams failed: %m");
+ return (0);
+ }
+
+ /* nb. only turn things on, if someone else has turned something
+ * on before we get here, leave it alone!
+ */
+
+ if (instance->assert) { /* nb, default or ON */
instance->pps_p.mode = PPS_CAPTUREASSERT | PPS_OFFSETASSERT;
instance->pps_p.assert_offset.tv_sec = 0;
instance->pps_p.assert_offset.tv_nsec = 0;
@@ -457,16 +505,41 @@ oncore_start(
instance->pps_p.clear_offset.tv_nsec = 0;
}
instance->pps_p.mode |= PPS_TSFMT_TSPEC;
+ instance->pps_p.mode &= mode; /* only do it if it is legal */
+
if (time_pps_setparams(instance->pps_h, &instance->pps_p) < 0) {
perror("time_pps_setparams");
exit(1);
}
- if (time_pps_kcbind(instance->pps_h, PPS_KC_HARDPPS,
- instance->pps_p.mode & (PPS_CAPTUREASSERT | PPS_CAPTURECLEAR),
- PPS_TSFMT_TSPEC) < 0) {
- perror("time_pps_kcbind");
+
+ if (pps_device) {
+ if (stat(pps_device, &stat1)) {
+ perror("ONCORE: stat pps_device");
+ return(0);
+ }
+
+ /* must have hardpps ON, and fd2 must be the same device as on the pps line */
+
+ if (pps_hardpps && ((stat1.st_dev == stat2.st_dev) && (stat1.st_ino == stat2.st_ino))) {
+ int i;
+
+ if (instance->assert)
+ i = PPS_CAPTUREASSERT;
+ else
+ i = PPS_CAPTURECLEAR;
+
+ if (i&mode) {
+ if (time_pps_kcbind(instance->pps_h, PPS_KC_HARDPPS, i,
+ PPS_TSFMT_TSPEC) < 0) {
+ msyslog(LOG_ERR,
+ "refclock_ioctl: time_pps_kcbind failed: %m");
+ return (0);
+ }
+ }
+ }
}
#endif
+
instance->pp = pp;
instance->peer = peer;
instance->o_state = ONCORE_NO_IDEA;
@@ -500,6 +573,7 @@ oncore_start(
* We send info from config to Oncore later.
*/
+ instance->timeout = 1;
mode = instance->init_type;
if (mode == 3 || mode == 4) {
oncore_sendmsg(instance->ttyfd, oncore_cmd_Cf, sizeof oncore_cmd_Cf);
@@ -514,10 +588,85 @@ oncore_start(
}
instance->pollcnt = 2;
-
return (1);
}
+
+
+static void
+oncore_init_shmem(struct instance *instance, char *filename)
+{
+#ifdef ONCORE_SHMEM_STATUS
+ int i, l, n;
+ char *buf;
+ struct msg_desc *mp;
+ static unsigned int oncore_shmem_length;
+
+ if (oncore_messages[0].shmem == 0) {
+ n = 1;
+ for (mp = oncore_messages; mp->flag[0]; mp++) {
+ mp->shmem = n;
+ /* Allocate space for multiplexed almanac */
+ if (!strcmp(mp->flag, "Cb")) {
+ oncore_shmem_Cb = n;
+ n += (mp->len + 2) * 34;
+ }
+ n += mp->len + 2;
+ }
+ oncore_shmem_length = n + 2;
+ fprintf(stderr, "ONCORE: SHMEM length: %d bytes\n", oncore_shmem_length);
+ }
+ instance->statusfd = open(filename, O_RDWR|O_CREAT|O_TRUNC, 0644);
+ if (instance->statusfd < 0) {
+ perror(filename);
+ exit(4);
+ }
+ buf = malloc(oncore_shmem_length);
+ if (buf == NULL) {
+ perror("malloc");
+ exit(4);
+ }
+ memset(buf, 0, sizeof(buf));
+ i = write(instance->statusfd, buf, oncore_shmem_length);
+ if (i != oncore_shmem_length) {
+ perror(filename);
+ exit(4);
+ }
+ free(buf);
+ instance->shmem = (u_char *) mmap(0, oncore_shmem_length,
+ PROT_READ | PROT_WRITE,
+#ifdef MAP_HASSEMAPHORE
+ MAP_HASSEMAPHORE |
+#endif
+ MAP_SHARED,
+ instance->statusfd, (off_t)0);
+ if (instance->shmem == MAP_FAILED) {
+ instance->shmem = 0;
+ close (instance->statusfd);
+ exit(4);
+ }
+ for (mp = oncore_messages; mp->flag[0]; mp++) {
+ l = mp->shmem;
+ instance->shmem[l + 0] = mp->len >> 8;
+ instance->shmem[l + 1] = mp->len & 0xff;
+ instance->shmem[l + 2] = '@';
+ instance->shmem[l + 3] = '@';
+ instance->shmem[l + 4] = mp->flag[0];
+ instance->shmem[l + 5] = mp->flag[1];
+ if (!strcmp(mp->flag, "Cb")) {
+ for (i = 1; i < 35; i++) {
+ instance->shmem[l + i * 35 + 0] = mp->len >> 8;
+ instance->shmem[l + i * 35 + 1] = mp->len & 0xff;
+ instance->shmem[l + i * 35 + 2] = '@';
+ instance->shmem[l + i * 35 + 3] = '@';
+ instance->shmem[l + i * 35 + 4] = mp->flag[0];
+ instance->shmem[l + i * 35 + 5] = mp->flag[1];
+ }
+ }
+ }
+#endif /* ONCORE_SHMEM_STATUS */
+}
+
/*
* Read Input file if it exists.
*/
@@ -603,11 +752,10 @@ oncore_read_config(
*/
FILE *fd;
- char *cp, line[100], units[2], device[20];
- int i, j, sign, lat_flg, long_flg, ht_flg, mode;
+ char *cp, *cc, *ca, line[100], units[2], device[20];
+ int i, sign, lat_flg, long_flg, ht_flg, mode;
double f1, f2, f3;
-
sprintf(device, "%s%d", INIT_FILE, instance->unit);
if ((fd=fopen(device, "r")) == NULL)
if ((fd=fopen(INIT_FILE, "r")) == NULL) {
@@ -618,22 +766,54 @@ oncore_read_config(
mode = 0;
lat_flg = long_flg = ht_flg = 0;
while (fgets(line, 100, fd)) {
- if ((cp=strchr(line, '#')))
+
+ /* Remove comments */
+ if ((cp = strchr(line, '#')))
*cp = '\0';
- i = strlen(line);
- for (j=0; j<i; j++) /* just in case lower case */
- if (islower((int)line[j]))
- line[j] = toupper(line[j]);
- for (j=0; j<i; j++) /* let them use `=' between terms */
- if (line[j] == '=')
- line[j] = ' ';
- for (j=0; j<i; j++)
- if (line[j] != ' ')
+
+ /* Remove trailing space */
+ for (i = strlen(line);
+ i > 0 && isascii((int)line[i - 1]) && isspace((int)line[i - 1]);
+ )
+ line[--i] = '\0';
+
+ /* Remove leading space */
+ for (cc = line; *cc && isascii((int)*cc) && isspace((int)*cc); cc++)
+ continue;
+
+ /* Stop if nothing left */
+ if (!*cc)
+ continue;
+
+ /* Lowercase the command and find the arg */
+ for (ca = cc; *ca; ca++) {
+ if (isascii((int)*ca) && islower((int)*ca)) {
+ *ca = toupper(*ca);
+ } else if (isascii((int)*ca) && isspace((int)*ca)) {
break;
- if (!strncmp(&line[j], "LAT", 3)) {
- j += 3;
+ } else if (*ca == '=') {
+ *ca = ' ';
+ break;
+ }
+ }
+
+ /* Remove space leading the arg */
+ for (; *ca && isascii((int)*ca) && isspace((int)*ca); ca++)
+ continue;
+
+ if (!strncmp(cc, "STATUS", 6)) {
+ oncore_init_shmem(instance, ca);
+ continue;
+ }
+
+ /* Uppercase argument as well */
+ for (cp = ca; *cp; cp++)
+ if (isascii((int)*cp) && islower((int)*cp))
+ *cp = toupper(*cp);
+
+ if (!strncmp(cc, "LAT", 3)) {
f1 = f2 = f3 = 0;
- sscanf(&line[j], "%lf %lf %lf", &f1, &f2, &f3);
+ sscanf(ca, "%lf %lf %lf", &f1, &f2, &f3);
sign = 1;
if (f1 < 0) {
f1 = -f1;
@@ -641,10 +821,9 @@ oncore_read_config(
}
instance->ss_lat = sign*1000*(fabs(f3) + 60*(fabs(f2) + 60*f1)); /*miliseconds*/
lat_flg++;
- } else if (!strncmp(&line[j], "LON", 3)) {
- j += 3;
+ } else if (!strncmp(cc, "LON", 3)) {
f1 = f2 = f3 = 0;
- sscanf(&line[j], "%lf %lf %lf", &f1, &f2, &f3);
+ sscanf(ca, "%lf %lf %lf", &f1, &f2, &f3);
sign = 1;
if (f1 < 0) {
f1 = -f1;
@@ -652,29 +831,24 @@ oncore_read_config(
}
instance->ss_long = sign*1000*(fabs(f3) + 60*(fabs(f2) + 60*f1)); /*miliseconds*/
long_flg++;
- } else if (!strncmp(&line[j], "HT", 2)) {
- instance->ss_ht_type = 0;
- if (!strncmp(&line[j], "HTGPS", 5)) {
+ } else if (!strncmp(cc, "HT", 2)) {
+ if (!strncmp(cc, "HTGPS", 5))
instance->ss_ht_type = 0;
- j +=3;
- }
- if (!strncmp(&line[j], "HTMSL", 5)) {
+ else if (!strncmp(cc, "HTMSL", 5))
instance->ss_ht_type = 1;
- j +=3;
- }
- j += 2;
+ else
+ instance->ss_ht_type = 0;
f1 = 0;
units[0] = '\0';
- sscanf(&line[j], "%lf %1s", &f1, units);
+ sscanf(ca, "%lf %1s", &f1, units);
if (units[0] == 'F')
f1 = 0.3048 * f1;
instance->ss_ht = 100 * f1; /* cm */
ht_flg++;
- } else if (!strncmp(&line[j], "DELAY", 5)) {
- j += 5;
+ } else if (!strncmp(cc, "DELAY", 5)) {
f1 = 0;
units[0] = '\0';
- sscanf(&line[j], "%lf %1s", &f1, units);
+ sscanf(ca, "%lf %1s", &f1, units);
if (units[0] == 'N')
;
else if (units[0] == 'U')
@@ -686,11 +860,10 @@ oncore_read_config(
if (f1 < 0 || f1 > 1.e9)
f1 = 0;
instance->delay = f1; /* delay in ns */
- } else if (!strncmp(&line[j], "OFFSET", 6)) {
- j += 6;
+ } else if (!strncmp(cc, "OFFSET", 6)) {
f1 = 0;
units[0] = '\0';
- sscanf(&line[j], "%lf %1s", &f1, units);
+ sscanf(ca, "%lf %1s", &f1, units);
if (units[0] == 'N')
;
else if (units[0] == 'U')
@@ -702,15 +875,14 @@ oncore_read_config(
if (f1 < 0 || f1 > 1.e9)
f1 = 0;
instance->offset = f1; /* offset in ns */
- } else if (!strncmp(&line[j], "MODE", 4)) {
- j += 4;
- sscanf(&line[j], "%d", &mode);
+ } else if (!strncmp(cc, "MODE", 4)) {
+ sscanf(ca, "%d", &mode);
if (mode < 0 || mode > 4)
mode = 4;
instance->init_type = mode;
- } else if (!strncmp(&line[j], "ASSERT", 6)) {
+ } else if (!strncmp(cc, "ASSERT", 6)) {
instance->assert = 1;
- } else if (!strncmp(&line[j], "CLEAR", 5)) {
+ } else if (!strncmp(cc, "CLEAR", 5)) {
instance->assert = 0;
}
}
@@ -763,6 +935,16 @@ oncore_poll(
struct instance *instance;
instance = (struct instance *) peer->procptr->unitptr;
+ if (instance->timeout) {
+ char *cp;
+
+ oncore_sendmsg(instance->ttyfd, oncore_cmd_Cj, sizeof oncore_cmd_Cj);
+ instance->o_state = ONCORE_ID_SENT;
+ cp = "state = ONCORE_ID_SENT";
+ record_clock_stats(&(instance->peer->srcadr), cp);
+ return;
+ }
+
if (!instance->pollcnt)
refclock_report(peer, CEVNT_TIMEOUT);
else
@@ -822,7 +1004,8 @@ oncore_consume(
struct instance *instance
)
{
- int i, l, j, m;
+ int i, j, m;
+ unsigned l;
while (rcvptr >= 7) {
if (rcvbuf[0] != '@' || rcvbuf[1] != '@') {
@@ -858,6 +1041,9 @@ oncore_consume(
for (i = 2; i < l-3; i++)
j ^= rcvbuf[i];
if (j == rcvbuf[l-3]) {
+ if (instance->shmem != NULL)
+ memcpy(instance->shmem + oncore_messages[m].shmem + 2,
+ rcvbuf, l);
oncore_msg_any(instance, rcvbuf, (unsigned) (l-3), m);
if (oncore_messages[m].handler)
oncore_messages[m].handler(instance, rcvbuf, (unsigned) (l-3));
@@ -942,6 +1128,33 @@ oncore_msg_any(
/*
+ * Demultiplex the almanac into shmem
+ */
+static void
+oncore_msg_Cb(
+ struct instance *instance,
+ u_char *buf,
+ u_int len
+ )
+{
+ int i;
+
+ if (instance->shmem == NULL)
+ return;
+
+ if (buf[4] == 5)
+ i = buf[5];
+ else if (buf[4] == 4 && buf[5] <= 5)
+ i = buf[5] + 24;
+ else if (buf[4] == 4 && buf[5] <= 10)
+ i = buf[5] + 23;
+ else
+ i = 34;
+ i *= 35;
+ memcpy(instance->shmem + oncore_shmem_Cb + i + 2, buf, len + 3);
+}
+
+/*
* Set to Factory Defaults (Reasonable for UT w/ no Battery Backup
* not so for VP (eeprom) or UT with battery
*/
@@ -964,6 +1177,15 @@ oncore_msg_Cf(
+/* there are good reasons NOT to do a @@Fa command with the ONCORE.
+ * Doing it, it was found that under some circumstances the following
+ * command would fail if issued immediately after the return from the
+ * @@Fa, but a 2sec delay seemed to fix things. Since simply calling
+ * sleep(2) is wastefull, and may cause trouble for some OS's, repeating
+ * itimer, we set a flag, and test it at the next POLL. If it hasnt
+ * been cleared, we reissue the @@Ca that is issued below.
+ */
+
static void
oncore_msg_Fa(
struct instance *instance,
@@ -981,12 +1203,6 @@ oncore_msg_Fa(
exit(1);
}
- /* sometimes the @@Cj request does not produce any output
- PERHAPS the ONCORE is still busy from the selftest???
- try a 2 second sleep here to see if it makes any difference
- */
-
- sleep(2);
oncore_sendmsg(instance->ttyfd, oncore_cmd_Cj, sizeof oncore_cmd_Cj);
instance->o_state = ONCORE_ID_SENT;
cp = "state = ONCORE_ID_SENT";
@@ -1006,19 +1222,41 @@ oncore_msg_Cj(
u_int len
)
{
- const char *cp;
+ char *cp, *cp1;
int mode;
+ instance->timeout = 0;
if (instance->o_state != ONCORE_ID_SENT)
return;
memcpy(instance->Cj, buf, len);
+ /* Write Receiver ID to clockstats file */
+
+ instance->Cj[294] = '\0';
+ for (cp=(char *)instance->Cj; cp< (char *) &instance->Cj[294]; ) {
+ cp1 = strchr(cp, '\r');
+ if (!cp1)
+ cp1 = (char *)&instance->Cj[294];
+ *cp1 = '\0';
+ record_clock_stats(&(instance->peer->srcadr), cp);
+ *cp1 = '\r';
+ cp = cp1+2;
+ }
+#ifdef HAVE_PPSAPI
+ if (instance->assert)
+ cp = "Timing on Assert.";
+ else
+ cp = "Timing on Clear.";
+ record_clock_stats(&(instance->peer->srcadr), cp);
+#endif
+
oncore_sendmsg(instance->ttyfd, oncore_cmd_Cg, sizeof oncore_cmd_Cg); /* Set Posn Fix mode (not Idle (VP)) */
oncore_sendmsg(instance->ttyfd, oncore_cmd_Bb, sizeof oncore_cmd_Bb); /* turn off */
oncore_sendmsg(instance->ttyfd, oncore_cmd_Ek, sizeof oncore_cmd_Ek); /* turn off */
oncore_sendmsg(instance->ttyfd, oncore_cmd_Aw, sizeof oncore_cmd_Aw); /* UTC time */
oncore_sendmsg(instance->ttyfd, oncore_cmd_AB, sizeof oncore_cmd_AB); /* Appl type static */
+ oncore_sendmsg(instance->ttyfd, oncore_cmd_Be, sizeof oncore_cmd_Be); /* Tell us the Almanac */
mode = instance->init_type;
if (debug)
@@ -1094,6 +1332,7 @@ oncore_msg_Ea(
)
{
const char *cp;
+ char Msg[160];
if (instance->o_state != ONCORE_ALMANAC && instance->o_state != ONCORE_RUN)
return;
@@ -1128,6 +1367,7 @@ oncore_msg_Ea(
/* Read back Position Hold Params */
oncore_sendmsg(instance->ttyfd, oncore_cmd_Asx, sizeof oncore_cmd_Asx);
/* Read back PPS Offset for Output */
+ /* Nb. This will fail silently for early UT (no plus) model */
oncore_sendmsg(instance->ttyfd, oncore_cmd_Ayx, sizeof oncore_cmd_Ayx);
/* Read back Cable Delay for Output */
oncore_sendmsg(instance->ttyfd, oncore_cmd_Azx, sizeof oncore_cmd_Azx);
@@ -1184,14 +1424,6 @@ oncore_msg_Ea(
instance->ss_ht += buf_w32(&instance->Ea[23]); /* GPS ellipse */
instance->ss_count++;
- if (debug)
- printf("ONCORE: AVG %d %d %d %d\n",
- instance->ss_count,
- (unsigned) (instance->ss_lat / instance->ss_count),
- (unsigned) (instance->ss_long / instance->ss_count),
- (unsigned) (instance->ss_ht / instance->ss_count)
- );
-
if (instance->ss_count != POS_HOLD_AVERAGE)
return;
@@ -1199,6 +1431,10 @@ oncore_msg_Ea(
instance->ss_long /= POS_HOLD_AVERAGE;
instance->ss_ht /= POS_HOLD_AVERAGE;
+ sprintf(Msg, "Surveyed posn: lat %.3f long %.3f ht %.3f",
+ instance->ss_lat, instance->ss_long, instance->ss_ht);
+ record_clock_stats(&(instance->peer->srcadr), Msg);
+
w32_buf(&oncore_cmd_As[2], (int) instance->ss_lat);
w32_buf(&oncore_cmd_As[6], (int) instance->ss_long);
w32_buf(&oncore_cmd_As[10], (int) instance->ss_ht);
@@ -1240,6 +1476,9 @@ oncore_msg_En(
struct ppsclockev ev;
int r = TIOCGPPSEV;
#endif
+#if TIOCDCDTIMESTAMP
+ struct timeval tv;
+#endif
#endif /* ! HAVE_PPS_API */
if (instance->o_state != ONCORE_RUN)
@@ -1311,7 +1550,8 @@ oncore_msg_En(
DTOLFP(dmy, &ts);
ts.l_ui = tsp->tv_sec;
#endif /* 0 */
-#else /* ! HAVE_PPSAPI */
+#else
+# if defined(HAVE_TIOCGPPSEV) || defined(HAVE_CIOGETEV)
j = instance->ev_serial;
if (ioctl(instance->ppsfd, r, (caddr_t) &ev) < 0) {
perror("ONCORE: IOCTL:");
@@ -1333,6 +1573,18 @@ oncore_msg_En(
/* convert timeval -> ntp l_fp */
TVTOTS(tsp, &ts);
+# else
+# if defined(TIOCDCDTIMESTAMP)
+ if(ioctl(instance->ppsfd, TIOCDCDTIMESTAMP, &tv) < 0) {
+ perror("ONCORE: ioctl(TIOCDCDTIMESTAMP)");
+ return;
+ }
+ tsp = &tv;
+ TVTOTS(tsp, &ts);
+# else
+#error "Cannot compile -- no PPS mechanism configured!"
+# endif
+# endif
#endif
/* now have timestamp in ts */
/* add in saw_tooth and offset */
@@ -1427,19 +1679,25 @@ oncore_msg_At(
u_int len
)
{
-
if (instance->site_survey != ONCORE_SS_UNKNOWN)
return;
- if (buf[4] == 2)
+ if (buf[4] == 2) {
+ record_clock_stats(&(instance->peer->srcadr),
+ "Initiating hardware 3D site survey");
instance->site_survey = ONCORE_SS_HW;
- else {
- instance->site_survey = ONCORE_SS_SW;
-
+ } else {
+ char Msg[160];
/*
* Probably a VP or an older UT which can't do site-survey.
* We will have to do it ourselves
*/
+
+ sprintf(Msg, "Initiating software 3D site survey (%d samples)",
+ POS_HOLD_AVERAGE);
+ record_clock_stats(&(instance->peer->srcadr), Msg);
+ instance->site_survey = ONCORE_SS_SW;
+
oncore_cmd_At[2] = 0;
instance->ss_lat = instance->ss_long = instance->ss_ht = 0;
oncore_sendmsg(instance->ttyfd, oncore_cmd_At, sizeof oncore_cmd_At);
@@ -1497,7 +1755,11 @@ oncore_msg_As(
u_int len
)
{
- int lat, lon, ht;
+ char Msg[120], ew, ns;
+ const char *Ht;
+ double xd, xm, xs, yd, ym, ys, hm, hft;
+ int idx, idy, is, imx, imy;
+ long lat, lon, ht;
if (!instance->printed || instance->As)
return;
@@ -1515,86 +1777,7 @@ oncore_msg_As(
instance->ss_ht_type = buf[16];
- if (instance->Ay && instance->Az)
- oncore_stats(instance);
-}
-
-
-
-/*
- * get PPS Offset
- */
-static void
-oncore_msg_Ay(
- struct instance *instance,
- u_char *buf,
- u_int len
- )
-{
- if (!instance->printed || instance->Ay)
- return;
-
- instance->Ay = 1;
-
- instance->offset = buf_w32(&buf[4]);
-
- if (instance->As && instance->Az)
- oncore_stats(instance);
-}
-
-
-
-/*
- * get Cable Delay
- */
-static void
-oncore_msg_Az(
- struct instance *instance,
- u_char *buf,
- u_int len
- )
-{
- if (!instance->printed || instance->Az)
- return;
-
- instance->Az = 1;
-
- instance->delay = buf_w32(&buf[4]);
-
- if (instance->As && instance->Ay)
- oncore_stats(instance);
-}
-
-
-
-/*
- * print init data in ONCORE to clockstats file
- */
-static void
-oncore_stats(
- struct instance *instance
- )
-{
- char Msg[120], ew, ns, *cp, *cp1;
- const char *Ht;
- double xd, xm, xs, yd, ym, ys, hm, hft;
- int idx, idy, is, imx, imy;
- long lat, lon;
-
- /* First, Receiver ID */
-
- instance->Cj[294] = '\0';
- for (cp=(char *)instance->Cj; cp< (char *) &instance->Cj[294]; ) {
- cp1 = strchr(cp, '\r');
- if (!cp1)
- cp1 = (char *)&instance->Cj[294];
- *cp1 = '\0';
- record_clock_stats(&(instance->peer->srcadr), cp);
- *cp1 = '\r';
- cp = cp1+2;
- }
-
- /* Next Position */
+ /* Print out Position */
record_clock_stats(&(instance->peer->srcadr), "Posn:");
ew = 'E';
@@ -1637,24 +1820,58 @@ oncore_stats(
ys = is/1000.;
sprintf(Msg, "Lat = %c %3ddeg %2dm %5.2fs, Long = %c %3ddeg %2dm %5.2fs, Alt = %5.2fm (%5.2fft) %s", ns, idx, imx, xs, ew, idy, imy, ys, hm, hft, Ht);
record_clock_stats(&(instance->peer->srcadr), Msg);
+}
- /* finally, cable delay and PPS offset */
- sprintf(Msg, "Cable delay is set to %ld ns", instance->delay);
- record_clock_stats(&(instance->peer->srcadr), Msg);
+
+/*
+ * get PPS Offset
+ * Nb. @@Ay is not supported for early UT (no plus) model
+ */
+static void
+oncore_msg_Ay(
+ struct instance *instance,
+ u_char *buf,
+ u_int len
+ )
+{
+ char Msg[120];
+
+ if (!instance->printed || instance->Ay)
+ return;
+
+ instance->Ay = 1;
+
+ instance->offset = buf_w32(&buf[4]);
sprintf(Msg, "PPS Offset is set to %ld ns", instance->offset);
record_clock_stats(&(instance->peer->srcadr), Msg);
-
-#ifdef HAVE_PPSAPI
- if (instance->assert)
- cp = "Timing on Assert.";
- else
- cp = "Timing on Clear.";
- record_clock_stats(&(instance->peer->srcadr), cp);
-#endif
}
+
+
+/*
+ * get Cable Delay
+ */
+static void
+oncore_msg_Az(
+ struct instance *instance,
+ u_char *buf,
+ u_int len
+ )
+{
+ char Msg[120];
+
+ if (!instance->printed || instance->Az)
+ return;
+
+ instance->Az = 1;
+
+ instance->delay = buf_w32(&buf[4]);
+
+ sprintf(Msg, "Cable delay is set to %ld ns", instance->delay);
+ record_clock_stats(&(instance->peer->srcadr), Msg);
+}
#else
int refclock_oncore_bs;
#endif /* REFCLOCK */
OpenPOWER on IntegriCloud