23 #include "../client/pps-client.h"
47 const char *
num =
"0123456789.";
51 static struct stat configFileStat;
52 static time_t modifyTime = 0;
53 static int lastJitterFileno = 0;
54 static int lastErrorFileno = 0;
55 static struct timespec offset_assert = {0, 0};
110 int List::binaryInsert(
int val){
118 if (ln == 0 || val > lst[high].val){
123 if (val < lst[0].val){
127 if (val > lst[0].val){
136 while ((high - low) > 1){
137 j = (high + low) / 2;
138 if (val <= lst[j].val){
145 if (lst[high].val == val){
146 lst[high].nVals += 1;
164 double List::averageBelow(
int maxVal){
174 for (
int i = 0; i < ln; i++){
175 sum += lst[i].nVals * lst[i].val;
179 if (lst[i+1].val - lst[i].val >= maxVal){
185 average = (double)sum / (
double)n;
194 int rv = system(cmd);
195 if (rv == -1 || WIFEXITED(rv) ==
false){
196 sprintf(
g.logbuf,
"System command failed: %s\n", cmd);
215 int i = round(log2(key));
217 if (
g.config_select & key){
219 str =
g.configVals[i];
223 while (str[len-1] ==
' '){
254 int i = round(log2(key));
256 if (
g.config_select & key){
257 char *val = strstr(
g.configVals[i],
string);
299 {
"frequency-vars", NULL,
"/var/local/pps-frequency-vars", 0, 3, 0},
300 {
"pps-offsets", NULL,
"/var/local/pps-offsets", 0, 4, 0}
307 strcpy(logbuf,
"ERROR: could not open \"");
308 strcat(logbuf, filename);
309 strcat(logbuf,
"\": ");
310 strcat(logbuf, strerror(errno));
312 strcat(logbuf, location);
313 strcat(logbuf,
"\n");
320 strcpy(logbuf,
"ERROR: reading \"");
321 strcat(logbuf, filename);
322 strcat(logbuf,
"\" was interrupted: ");
323 strcat(logbuf, strerror(errno));
324 strcat(logbuf,
"\n");
337 stat(
f.log_file, &info);
338 if (info.st_size > 100000){
339 remove(
f.old_log_file);
340 rename(
f.log_file,
f.old_log_file);
343 mode_t mode = S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH;
344 int fd = open(
f.log_file, O_CREAT | O_WRONLY | O_APPEND, mode);
347 printf(
"%s", logbuf);
351 int rv = write(fd, logbuf, strlen(logbuf));
369 stat(
f.log_file, &info);
370 if (info.st_size > 100000){
371 remove(
f.old_log_file);
372 rename(
f.log_file,
f.old_log_file);
375 mode_t mode = S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH;
376 int fd = open(
f.log_file, O_CREAT | O_WRONLY | O_APPEND, mode);
379 printf(
"%s", logbuf);
383 time_t t = time(NULL);
384 struct tm *tmp = localtime(&t);
385 strftime(
g.strbuf,
STRBUF_SZ-1,
"%F %H:%M:%S ", tmp);
386 int rv = write(fd,
g.strbuf, strlen(
g.strbuf));
391 rv = write(fd, logbuf, strlen(logbuf));
410 fprintf(stdout,
"%s", msg);
413 int msglen = strlen(
g.savebuf) + 10;
414 int parmslen = strlen(msg);
420 strcat(
g.savebuf, msg);
437 int fSize = strlen(
g.savebuf);
439 remove(
f.displayParams_file);
440 int fd =
open_logerr(
f.displayParams_file, O_CREAT | O_WRONLY,
"writeStatusStrings() 1");
444 int rv = write(fd,
g.savebuf, fSize);
447 sprintf(
g.logbuf,
"writeStatusStrings() Could not write to %s. Error: %s\n",
f.displayParams_file, strerror(errno));
467 int rv = read(fd, buf, sz);
486 int open_logerr(
const char* filename,
int flags,
const char *location){
487 int mode = S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH;
489 if ((flags & O_CREAT) == O_CREAT){
490 fd = open(filename, flags, mode);
493 fd = open(filename, flags);
512 int fd =
open_logerr(
f.integral_state_file, O_CREAT | O_WRONLY,
"saveLastState()");
517 memset(buf, 0, 500 *
sizeof(
char));
522 while (*pbuf !=
'\0'){
528 while (*pbuf !=
'\0'){
533 while (*pbuf !=
'\0'){
538 while (*pbuf !=
'\0'){
543 while (*pbuf !=
'\0'){
548 while (*pbuf !=
'\0'){
554 while (*pbuf !=
'\0'){
560 while (*pbuf !=
'\0'){
565 while (*pbuf !=
'\0'){
570 while (*pbuf !=
'\0'){
575 while (*pbuf !=
'\0'){
580 while (*pbuf !=
'\0'){
585 while (*pbuf !=
'\0'){
590 while (*pbuf !=
'\0'){
594 int rv = write(fd, buf, strlen(buf) + 1);
613 int fd = open(
f.integral_state_file, O_RDONLY);
629 while (*pbuf !=
'\n'){
636 sscanf(pbuf,
"%d\n", &b);
642 while (*pbuf !=
'\n'){
648 while (*pbuf !=
'\n'){
654 while (*pbuf !=
'\n'){
660 while (*pbuf !=
'\n'){
666 while (*pbuf !=
'\n'){
674 while (*pbuf !=
'\n'){
681 while (*pbuf !=
'\n'){
687 while (*pbuf !=
'\n'){
693 while (*pbuf !=
'\n'){
699 while (*pbuf !=
'\n'){
705 while (*pbuf !=
'\n'){
711 sscanf(pbuf,
"%d\n", &t_f);
718 while (*pbuf !=
'\n'){
724 while (*pbuf !=
'\n'){
733 g.
t3.modes = ADJ_FREQUENCY;
751 struct stat stat_buf;
754 int fd = open(filename, O_RDONLY);
757 printf(
"%s", logbuf);
760 fstat(fd, &stat_buf);
761 int sz = stat_buf.st_size;
767 printf(
"%s", logbuf);
773 rv = read(fd, logbuf, sz);
776 printf(
"%s", logbuf);
809 int pfd =
open_logerr(
f.pidFilename, O_RDONLY,
"getChildPID()");
817 sscanf(
g.strbuf,
"%d\n", &pid);
835 memset(cmdbuf, 0, 100 *
sizeof(
char));
836 strcpy(cmdbuf,
"pidof pps-client > ");
837 strcat(cmdbuf,
f.pps_msg_file);
844 int fd = open(
f.pps_msg_file, O_RDONLY);
846 sprintf(
g.logbuf,
"ppsIsRunning() Failed. Could not open %s. Error: %s\n",
f.pps_msg_file, strerror(errno));
850 memset(buf, 0, 50 *
sizeof(
char));
851 rv = read(fd, buf, 50);
853 sprintf(
g.logbuf,
"ppsIsRunning() Failed. Could not read %s. Error: %s\n",
f.pps_msg_file, strerror(errno));
858 int callerPID = 0, daemonPID = 0;
859 sscanf(buf,
"%d %d\n", &callerPID, &daemonPID);
862 remove(
f.pps_msg_file);
878 int rv = stat(
f.pidFilename, &buf);
880 rv = remove(
f.pidFilename);
886 int pfd =
open_logerr(
f.pidFilename, O_RDWR | O_CREAT | O_EXCL,
"createPIDfile()");
891 pid_t ppid = getpid();
893 sprintf(
g.strbuf,
"%d\n", ppid);
894 if (write(pfd,
g.strbuf, strlen(
g.strbuf)) == -1)
897 sprintf(
g.logbuf,
"createPIDfile() Could not write a PID file. Error: %s\n", strerror(errno));
924 struct stat stat_buf;
926 int rvs = stat(fconfig, &configFileStat);
928 sprintf(
g.logbuf,
"readConfigFile(): Config file not found.\n");
933 timespec t = configFileStat.st_mtim;
939 modifyTime = t.tv_sec;
941 int fd =
open_logerr(fconfig, O_RDONLY,
"readConfigFile()");
946 fstat(fd, &stat_buf);
947 int sz = stat_buf.st_size;
950 sprintf(
g.logbuf,
"readConfigFile(): not enough space allocated for config file.\n");
956 if (rv == -1 || sz != rv){
961 g.configBuf[sz] =
'\0';
966 char *pToken = strtok(
g.configBuf,
"\n");
968 while (pToken != NULL){
969 if (strlen(pToken) != 0){
970 for (
int j = 0; j < 10; j++){
971 if (pToken[0] ==
' '){
979 if (pToken[0] !=
'#'){
980 g.configVals[nCfgStrs] = pToken;
984 pToken = strtok(NULL,
"\n");
991 for (i = 0; i < nCfgStrs; i++){
993 strcpy(
g.configBuf,
g.configVals[i]);
996 strcat(
g.configBuf,
g.configVals[i]);
998 strcat(
g.configBuf,
"\n");
1001 int nValidCnfgs =
sizeof(
valid_config) /
sizeof(
char *);
1003 char **configVal =
g.configVals;
1006 for (i = 0; i < nValidCnfgs; i++){
1010 g.config_select |= 1 << i;
1012 value = strpbrk(found,
"=");
1015 configVal[i] = value;
1018 g.config_select &= ~(1 << i);
1019 configVal[i] = NULL;
1023 for (i = 0; i < nValidCnfgs; i++){
1024 if (configVal[i] != NULL){
1025 value = strpbrk(configVal[i],
"\n");
1063 for (
int i = 0; i < len; i++){
1064 sprintf(
g.strbuf,
"%d %d\n", i-scaleZero, distrib[i]);
1065 rv = write(fd,
g.strbuf, strlen(
g.strbuf));
1067 sprintf(
g.logbuf,
"writeDistribution() Unable to write to %s. Error: %s\n",
distrib_file, strerror(errno));
1076 if (epoch != *last_epoch ){
1077 *last_epoch = epoch;
1080 memset(distrib, 0, len *
sizeof(
int));
1094 &lastJitterFileno,
f.jitter_distrib_file,
f.last_jitter_distrib_file);
1108 g.errorCount, &lastErrorFileno,
f.distrib_file,
f.last_distrib_file);
1119 int fd =
open_logerr(filename, O_CREAT | O_WRONLY | O_TRUNC,
"writeOffsets()");
1124 int j =
g.recIndex2 + i;
1128 sprintf(
g.strbuf,
"%d %d %lf\n",
g.seq_numRec[j],
g.offsetRec[j],
g.freqOffsetRec2[j]);
1129 int rv = write(fd,
g.strbuf, strlen(
g.strbuf));
1131 sprintf(
g.logbuf,
"writeOffsets() Unable to write to %s. Error: %s\n", filename, strerror(errno));
1146 int fd =
open_logerr(filename, O_CREAT | O_WRONLY | O_TRUNC,
"writeFrequencyVars()");
1151 int j =
g.recIndex + i;
1155 sprintf(
g.strbuf,
"%ld %lf %lf\n",
g.timestampRec[j],
g.freqOffsetRec[j],
g.freqAllanDev[j]);
1156 int rv = write(fd,
g.strbuf, strlen(
g.strbuf));
1158 sprintf(
g.logbuf,
"writeFrequencyVars() Write to %s failed with error: %s\n", filename, strerror(errno));
1179 int fd =
open_logerr(filename, O_CREAT | O_WRONLY | O_TRUNC,
"saveDoubleArray()");
1185 char *filebuf =
new char[fileMaxLen];
1189 for (
int i = 0; i < len; i++){
1190 sprintf(
g.strbuf,
"%d %7.2lf\n", i - arrayZero, distrib[i]);
1191 fileLen += strlen(
g.strbuf);
1192 strcat(filebuf,
g.strbuf);
1195 int rv = write(fd, filebuf, fileLen + 1);
1197 sprintf(
g.logbuf,
"saveDoubleArray() Write to %s failed with error: %s\n", filename, strerror(errno));
1222 int rv = stat(
f.arrayData_file, &buf);
1227 int fd = open(
f.arrayData_file, O_RDONLY);
1229 sprintf(
g.logbuf,
"processWriteRequest() Unable to open %s. Error: %s\n",
f.arrayData_file, strerror(errno));
1234 char requestStr[25];
1239 sscanf(
g.strbuf,
"%s %s", requestStr, filename);
1242 remove(
f.arrayData_file);
1244 int arrayLen =
sizeof(
arrayData) /
sizeof(
struct saveFileData);
1245 for (
int i = 0; i < arrayLen; i++){
1246 if (strcmp(requestStr,
arrayData[i].label) == 0){
1247 if (strlen(filename) == 0){
1248 strcpy(filename,
arrayData[i].filename);
1284 strcpy(
f.pidFilename, sp);
1290 strcpy(
f.assert_file, sp);
1293 strcpy(
f.displayParams_file, sp);
1296 strcpy(
f.arrayData_file, sp);
1299 strcpy(
f.pps_msg_file, sp);
1305 strcpy(
f.last_distrib_file, sp);
1308 strcpy(
f.distrib_file, sp);
1311 strcpy(
f.last_jitter_distrib_file, sp);
1314 strcpy(
f.home_file, sp);
1320 strcpy(
f.log_file, sp);
1323 strcpy(
f.old_log_file, sp);
1339 strcpy(
g.serialPort, sp);
1406 struct stat dirStat;
1411 rv = stat(sp, &dirStat);
1413 printf(
"Invalid path for rundir. %s: %s\n", strerror(errno), sp);
1417 strcpy(
f.pidFilename, sp);
1424 rv = stat(sp, &dirStat);
1426 printf(
"Invalid path for shmdir in pps-client.conf. %s: %s\n", strerror(errno), sp);
1430 strcpy(
f.assert_file, sp);
1433 strcpy(
f.displayParams_file, sp);
1436 strcpy(
f.arrayData_file, sp);
1439 strcpy(
f.pps_msg_file, sp);
1442 strcpy(
f.linuxVersion_file, sp);
1445 strcpy(
f.gmtTime_file, sp);
1448 strcpy(
f.nistTime_file, sp);
1455 rv = stat(sp, &dirStat);
1457 printf(
"Invalid path for tstdir in pps-client.conf. %s: %s\n", strerror(errno), sp);
1461 strcpy(
f.last_distrib_file, sp);
1464 strcpy(
f.distrib_file, sp);
1467 strcpy(
f.last_jitter_distrib_file, sp);
1470 strcpy(
f.jitter_distrib_file, sp);
1473 strcpy(
f.home_file, sp);
1480 rv = stat(sp, &dirStat);
1482 printf(
"Invalid path for logdir in pps-client.conf. %s: %s\n", strerror(errno), sp);
1486 strcpy(
f.log_file, sp);
1489 strcpy(
f.old_log_file, sp);
1496 rv = stat(sp, &dirStat);
1498 printf(
"Invalid path for ppsdevice in pps-client.conf. %s: %s\n", strerror(errno), sp);
1502 strcpy(
f.pps_device, sp);
1515 printf(
"Invalid value for segregate in pps-client.conf\n");
1525 printf(
"Invalid value for ppsphase in pps-client.conf. Must be 0 or 1.\n");
1533 rv = stat(sp, &dirStat);
1535 printf(
"Invalid path for procdir in pps-client.conf. %s: %s\n", strerror(errno), sp);
1539 strcpy(
f.cpuinfo_file, sp);
1562 strcpy(
g.serialPort, sp);
1566 g.exitOnLostPPS =
true;
1569 g.exitOnLostPPS =
false;
1584 sprintf(
g.strbuf,
"%lf#%d\n", timestamp,
g.
seq_num);
1585 remove(
f.assert_file);
1587 int pfd =
open_logerr(
f.assert_file, O_CREAT | O_WRONLY,
"writeTimestamp() 1");
1591 int rv = write(pfd,
g.strbuf, strlen(
g.strbuf) + 1);
1593 sprintf(
g.logbuf,
"writeTimestamp() write to assert_file failed with error: %s\n", strerror(errno));
1616 char *str = strstr(buf, token);
1618 sprintf(
g.logbuf,
"alignNumbersAfter(): token not found. Exiting.\n");
1622 str += strlen(token);
1625 if (buf[pos] !=
'-'){
1626 memmove(str + 1, str, len - pos);
1654 int alignTokens(
const char *refToken,
int offset,
const char *token,
char *buf,
int len){
1658 char *str = strstr(buf, refToken);
1660 sprintf(
g.logbuf,
"alignTokens(): refToken not found. Exiting.\n");
1664 str += strlen(refToken);
1667 str = strstr(buf, token);
1669 sprintf(
g.logbuf,
"alignTokens(): token not found. Exiting.\n");
1675 while (pos2 < pos1 + offset){
1676 memmove(str + 1, str, len - pos2);
1696 const char *timefmt =
"%F %H:%M:%S";
1700 memset(timeStr, 0, 50 *
sizeof(
char));
1701 strftime(timeStr, 50, timefmt, localtime(&
g.pps_t_sec));
1703 char *printfmt =
g.strbuf;
1705 strcpy(printfmt,
"%s.%06d %d jitter: ");
1708 strcat(printfmt,
"%d freqOffset: %f avgCorrection: %f clamp: %d\n");
1711 strcat(printfmt,
"%d freqOffset: %f avgCorrection: %f clamp: %d*\n");
1714 sprintf(printStr, printfmt, timeStr,
g.pps_t_usec,
g.
seq_num,
1717 int len = strlen(printStr) + 1;
1722 len =
alignTokens(
"jitter:", 6,
"freqOffset:", printStr, len);
1730 len =
alignTokens(
"freqOffset:", 12,
"avgCorrection:", printStr, len);
1738 len =
alignTokens(
"avgCorrection:", 12,
"clamp:", printStr, len);
1757 char *pHead = NULL, *pTail = NULL, *pNxt = NULL;
1762 while (strlen(pLine) > 0){
1764 while (pLine != NULL){
1767 while (pNxt[0] ==
' ' || pNxt[0] ==
'\t'){
1771 if (strncmp(pNxt, key1, strlen(key1)) == 0){
1773 pNxt += strlen(key1);
1775 while (pNxt[0] ==
' ' || pNxt[0] ==
'\t'){
1779 if (strncmp(pNxt, key2, strlen(key2)) == 0){
1780 pNxt += strlen(key2);
1782 while (pNxt[0] ==
' ' || pNxt[0] ==
'\t' || pNxt[0] ==
'\n'){
1787 memmove(pHead, pTail, strlen(pTail)+1);
1792 pLine = strchr(pLine,
'\n') + 1;
1806 memset(cmdbuf, 0, 100 *
sizeof(
char));
1807 strcpy(cmdbuf,
"uname -r > ");
1808 strcat(cmdbuf,
f.linuxVersion_file);
1815 int fd = open(
f.linuxVersion_file, O_RDONLY);
1816 rv = read(fd, fbuf, 20);
1818 sprintf(
g.logbuf,
"getLinuxVersion(): Unable to read Linux version from %s\n",
f.linuxVersion_file);
1837 int fd =
open_logerr(
f.cpuinfo_file, O_RDONLY,
"getRPiCPU()");
1839 printf(
"getRPiCPU() Open f.cpuinfo_file failed\n");
1848 sprintf(
g.logbuf,
"getRPiCPU(): Unable to read from %s\n",
f.cpuinfo_file);
1856 char *pstr = strstr(filebuf,
"Raspberry Pi");
1858 if (strncmp(pstr,
"Raspberry Pi 3", 14) == 0){
1861 else if (strncmp(pstr,
"Raspberry Pi 4", 14) == 0){
1882 struct stat stat_buf;
1884 sprintf(cmdstr,
"printf 'Assigned PPS-Client to processor %d\n'",
g.
useCore);
1887 for (
int i =
g.
nCores - 1; i >= 0; i--){
1888 bitmask = bitmask << 1;
1894 memset(cmd, 0, 100);
1895 sprintf(cmd,
"taskset -p %d ", bitmask);
1897 const char *end =
" > /dev/null 2>&1";
1899 rv =
sysCommand(
"ps --no-headers -eo pid > /dev/shm/pid.txt");
1905 int fd = open(
"/dev/shm/pid.txt", O_RDONLY);
1910 fstat(fd, &stat_buf);
1911 int sz = stat_buf.st_size;
1913 char *fbuf =
new char[sz+1];
1915 rv = read(fd, fbuf, sz);
1924 char *pbuf = strtok(fbuf,
"\n");
1926 pbuf = strtok(NULL,
"\n\0");
1927 memset(cmdstr, 0, 100);
1928 strcpy(cmdstr, cmd);
1929 strcat(cmdstr, fbuf);
1930 strcat(cmdstr, end);
1938 while (pbuf != NULL){
1939 pbuf = strtok(NULL,
"\n\0");
1942 memset(cmdstr, 0, 100);
1943 strcpy(cmdstr, cmd);
1944 strcat(cmdstr, pbuf);
1945 strcat(cmdstr, end);
1958 for (
int i =
g.
nCores - 1; i >= 0; i--){
1959 bitmask = bitmask << 1;
1965 memset(cmdstr, 0, 100);
1966 sprintf(cmdstr,
"taskset -p %d `pidof pps-client` > /dev/null 2>&1", bitmask);
1989 pSpc = strpbrk((
char *)pbuf,
space);
1991 pNum = strpbrk(pSpc,
num);
1992 pSpc = strpbrk(pNum,
space);
1993 pNum = strpbrk(pSpc,
num);
1995 sscanf(pNum,
"%d ", &seqNum);
2006 struct timespec ts2;
2008 struct stat stat_buf;
2009 int seqNum = 0, lastSeqNum = -1;
2012 printf(
"\nSerial port, %s, is providing time of day from GPS Satellites\n\n",
g.serialPort);
2015 printf(
"\nNIST UDP time servers are providing time of day over the Internet\n\n");
2018 int dispTime = 500000;
2020 gettimeofday(&tv1, NULL);
2028 nanosleep(&ts2, NULL);
2030 int fd = open(
f.displayParams_file, O_RDONLY);
2032 printf(
"showStatusEachSecond(): Could not open f.displayParams_file");
2033 printf(
"%s",
f.displayParams_file);
2037 fstat(fd, &stat_buf);
2038 int sz = stat_buf.st_size;
2041 printf(
"showStatusEachSecond() buffer too small. sz: %d\n", sz);
2046 int rv = read(fd, paramsBuf, sz);
2049 printf(
"showStatusEachSecond() Read paramsBuf failed with error: %s\n", strerror(errno));
2056 paramsBuf[sz]=
'\0';
2058 char *sv = strstr(paramsBuf,
"jitter");
2062 if (seqNum != lastSeqNum){
2063 printf(
"%s", paramsBuf);
2069 if (seqNum != lastSeqNum){
2070 printf(
"%s", paramsBuf);
2073 lastSeqNum = seqNum;
2077 gettimeofday(&tv1, NULL);
2081 printf(
" Exiting PPS-Client status display\n");
2107 if (i == argc - 1 || argv[i+1][0] ==
'-'){
2108 printf(
"Error: Missing argument for %s.\n", argv[i]);
2126 int fd =
open_logerr(
f.arrayData_file, O_CREAT | O_WRONLY | O_TRUNC,
"daemonSaveArray()");
2128 printf(
"daemonSaveArray() Open f.arrayData_file failed\n");
2132 strcpy(buf, requestStr);
2134 if (filename != NULL){
2136 strcat(buf, filename);
2139 int rv = write(fd, buf, strlen(buf) + 1);
2142 sprintf(
g.logbuf,
"daemonSaveArray() Write to tmpfs memory file failed\n");
2154 printf(
"Accepts any of these:\n");
2155 int arrayLen =
sizeof(
arrayData) /
sizeof(
struct saveFileData);
2156 for (
int i = 0; i < arrayLen; i++){
2174 int arrayLen =
sizeof(
arrayData) /
sizeof(
struct saveFileData);
2177 for (i = 0; i < arrayLen; i++){
2178 if (strcmp(requestStr,
arrayData[i].label) == 0){
2183 printf(
"Arg \"%s\" not recognized\n", argv[i+1]);
2188 char *filename = NULL;
2189 for (
int j = 1; j < argc; j++){
2190 if (strcmp(argv[j],
"-f") == 0){
2192 printf(
"Requires a filename.\n");
2196 g.strbuf[strlen(argv[j+1])] =
'\0';
2197 filename =
g.strbuf;
2202 if (filename != NULL){
2203 printf(
"Writing to file: %s\n", filename);
2206 for (i = 0; i < arrayLen; i++){
2207 if (strcmp(requestStr,
arrayData[i].label) == 0){
2208 printf(
"Writing to default file: %s\n",
arrayData[i].filename);
2239 bool verbose =
false;
2244 remove(
f.pidFilename);
2250 printf(
"\nPPS-Client v%s is running.\n",
version);
2254 for (
int i = 1; i < argc; i++){
2255 if (strcmp(argv[i],
"-v") == 0){
2259 for (
int i = 1; i < argc; i++){
2260 if (strcmp(argv[i],
"-s") == 0){
2275 printf(
"Displaying second-by-second state params (ctrl-c to quit):\n");
2296 int idx = timeCorrection + len / 6;
2301 else if (idx > len){
2304 g.errorDistrib[idx] += 1;
2318 int idx = rawError + len / 3;
2323 else if (idx > len){
2326 g.jitterDistrib[idx] += 1;
2338 signal(SIGTERM, SIG_IGN);
2339 sprintf(
g.logbuf,
"Recieved SIGTERM\n");
2341 g.exit_requested =
true;
2351 signal(SIGHUP, SIG_IGN);
2370 g.freqOffsetDiff[
g.intervalCount] =
g.
freqOffset -
g.lastFreqOffset;
2373 g.intervalCount += 1;
2376 gettimeofday(&t, NULL);
2380 double diffSum = 0.0;
2382 diffSum +=
g.freqOffsetDiff[i] *
g.freqOffsetDiff[i];
2384 g.freqAllanDev[
g.recIndex] = sqrt(diffSum * norm * 0.5);
2386 g.timestampRec[
g.recIndex] = t.tv_sec;
2388 g.freqOffsetRec[
g.recIndex] =
g.freqOffsetSum * norm;
2395 g.intervalCount = 0;
2396 g.freqOffsetSum = 0.0;
2415 g.offsetRec[
g.recIndex2] = timeCorrection;
2439 ret = open(path, O_RDWR);
2442 sprintf(
g.logbuf,
"Unable to open device \"%s\" (%m)\n", path);
2443 fprintf(stderr,
"%s",
g.logbuf);
2445 sprintf(
g.logbuf,
"Is the PPS driver enabled?\n");
2446 fprintf(stderr,
"%s",
g.logbuf);
2452 ret = time_pps_create(ret, handle);
2454 sprintf(
g.logbuf,
"cannot create a PPS source from device "
2455 "\"%s\" (%m)\n", path);
2461 ret = time_pps_getcap(*handle, avail_mode);
2463 sprintf(
g.logbuf,
"cannot get capabilities (%m)\n");
2467 if ((*avail_mode & PPS_CAPTUREASSERT) == 0) {
2468 sprintf(
g.logbuf,
"cannot CAPTUREASSERT\n");
2474 ret = time_pps_getparams(*handle, ¶ms);
2476 sprintf(
g.logbuf,
"cannot get parameters (%m)\n");
2480 params.
mode |= PPS_CAPTUREASSERT;
2482 if ((*avail_mode & PPS_OFFSETASSERT) != 0) {
2483 params.
mode |= PPS_OFFSETASSERT;
2484 params.assert_offset = offset_assert;
2486 ret = time_pps_setparams(*handle, ¶ms);
2488 sprintf(
g.logbuf,
"cannot set parameters (%m)\n");
2507 struct timespec timeout;
2513 timeout.tv_nsec = 0;
2516 if (*avail_mode & PPS_CANWAIT){
2517 ret = time_pps_fetch(*handle, PPS_TSFMT_TSPEC, &infobuf, &timeout);
2521 ret = time_pps_fetch(*handle, PPS_TSFMT_TSPEC, &infobuf, &timeout);
2524 if (ret == -EINTR) {
2525 sprintf(
g.logbuf,
"readPPSTimestamp(): time_pps_fetch() got a signal!\n");
2534 tm[0] = (int)infobuf.assert_timestamp.tv_sec;
2535 tm[1] = (
int)(infobuf.assert_timestamp.tv_nsec / 1000);
2538 tm[0] = (int)infobuf.clear_timestamp.tv_sec;
2539 tm[1] = (
int)(infobuf.clear_timestamp.tv_nsec / 1000);
2549 memset(cmdStr, 0, 100);
2550 strcpy(cmdStr,
"echo $HOME > ");
2551 strcat(cmdStr,
f.home_file);
2555 int fd = open(
f.home_file, O_RDONLY);
2557 sprintf(
g.logbuf,
"getRootHome(): Unable to open file %s\n",
"./Home");
2562 memset(buf, 0, 100);
2564 int rv = read(fd, buf, 99);
2572 while (*pbuf !=
'/'){
2576 char *pbufEnd = pbuf;
2577 while(*pbufEnd !=
'\n'){
2582 strcpy(
f.integral_state_file, pbuf);
2585 remove(
f.home_file);