22 #include "../client/pps-client.h" 29 const char *
log_file =
"/var/log/pps-client.log";
48 const char *
num =
"0123456789.";
55 static struct ppsFilesVars {
56 struct stat configFileStat;
59 int lastSysDelayFileno;
62 int lastIntrptJitterFileno;
86 memset(&f, 0,
sizeof(
struct ppsFilesVars));
91 if (rv == -1 || WIFEXITED(rv) ==
false){
92 sprintf(
g.logbuf,
"System command failed: %s\n", cmd);
109 int i = round(log2(key));
111 if (
g.config_select & key){
112 return g.configVals[i];
138 int i = round(log2(key));
140 if (
g.config_select & key){
141 char *val = strstr(
g.configVals[i],
string);
184 {
"frequency-vars", NULL,
"/var/local/pps-frequency-vars", 0, 3, 0},
185 {
"pps-offsets", NULL,
"/var/local/pps-offsets", 0, 4, 0}
192 strcpy(logbuf,
"ERROR: could not open \"");
193 strcat(logbuf, filename);
194 strcat(logbuf,
"\": ");
195 strcat(logbuf, strerror(errno));
196 strcat(logbuf,
"\n");
203 strcpy(logbuf,
"ERROR: reading \"");
204 strcat(logbuf, filename);
205 strcat(logbuf,
"\" was interrupted: ");
206 strcat(logbuf, strerror(errno));
207 strcat(logbuf,
"\n");
221 if (info.st_size > 100000){
226 mode_t mode = S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH;
227 int fd = open(
log_file, O_CREAT | O_WRONLY | O_APPEND, mode);
230 printf(
"%s", logbuf);
234 int rv = write(fd, logbuf, strlen(logbuf));
253 if (info.st_size > 100000){
258 mode_t mode = S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH;
259 int fd = open(
log_file, O_CREAT | O_WRONLY | O_APPEND, mode);
262 printf(
"%s", logbuf);
266 time_t t = time(NULL);
267 struct tm *tmp = localtime(&t);
268 strftime(
g.strbuf,
STRBUF_SZ,
"%F %H:%M:%S ", tmp);
269 int rv = write(fd,
g.strbuf, strlen(
g.strbuf));
274 rv = write(fd, logbuf, strlen(logbuf));
293 fprintf(stdout,
"%s", msg);
296 int msglen = strlen(
g.savebuf);
297 int parmslen = strlen(msg);
303 strcat(
g.savebuf, msg);
318 int fSize = strlen(
g.savebuf);
325 int rv = write(fd,
g.savebuf, fSize);
328 sprintf(
g.logbuf,
"writeStatusStrings() Could not write to %s. Error: %s\n",
displayParams_file, strerror(errno));
348 int rv = read(fd, buf, sz);
367 int mode = S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH;
369 if ((flags & O_CREAT) == O_CREAT){
370 fd = open(filename, flags, mode);
373 fd = open(filename, flags);
394 struct stat stat_buf;
397 int fd = open(filename, O_RDONLY);
400 printf(
"%s", logbuf);
403 fstat(fd, &stat_buf);
404 int sz = stat_buf.st_size;
410 printf(
"%s", logbuf);
416 rv = read(fd, logbuf, sz);
419 printf(
"%s", logbuf);
449 const char *filename =
"/var/run/pps-client.pid";
461 sscanf(
g.strbuf,
"%d\n", &pid);
477 const char *filename =
"/run/shm/pps-msg";
479 int rv =
sysCommand(
"pidof pps-client > /run/shm/pps-msg");
484 int fd = open(filename, O_RDONLY);
486 sprintf(
g.logbuf,
"ppsIsRunning() Failed. Could not open %s. Error: %s\n", filename, strerror(errno));
491 rv = read(fd, buf, 50);
493 sprintf(
g.logbuf,
"ppsIsRunning() Failed. Could not read %s. Error: %s\n", filename, strerror(errno));
498 int callerPID = 0, daemonPID = 0;
499 sscanf(buf,
"%d %d\n", &callerPID, &daemonPID);
522 pid_t ppid = getpid();
524 sprintf(
g.strbuf,
"%d\n", ppid);
525 if (write(pfd,
g.strbuf, strlen(
g.strbuf)) == -1)
528 sprintf(
g.logbuf,
"createPIDfile() Could not write a PID file. Error: %s\n", strerror(errno));
551 int i = round(log2(config_val));
552 if (
g.config_select & config_val){
553 char *val = strpbrk(
g.configVals[i],
num);
554 if (strpbrk(val,
".") != NULL){
555 sscanf(val,
"%lf", (
double *)value);
558 sscanf(val,
"%d", (
int *)value);
628 struct stat stat_buf;
632 sprintf(
g.logbuf,
"readConfigFile(): Config file not found.\n");
637 timespec t = f.configFileStat.st_mtim;
643 f.modifyTime = t.tv_sec;
650 fstat(fd, &stat_buf);
651 int sz = stat_buf.st_size;
654 sprintf(
g.logbuf,
"readConfigFile(): not enough space allocated for config file.\n");
660 if (rv == -1 || sz != rv){
665 g.configBuf[sz] =
'\0';
670 char *pToken = strtok(
g.configBuf,
"\n");
672 while (pToken != NULL){
673 if (strlen(pToken) != 0){
674 for (
int j = 0; j < 10; j++){
675 if (pToken[0] ==
' '){
683 if (pToken[0] !=
'#'){
684 g.configVals[nCfgStrs] = pToken;
688 pToken = strtok(NULL,
"\n");
695 for (i = 0; i < nCfgStrs; i++){
697 strcpy(
g.configBuf,
g.configVals[i]);
700 strcat(
g.configBuf,
g.configVals[i]);
702 strcat(
g.configBuf,
"\n");
705 int nValidCnfgs =
sizeof(
valid_config) /
sizeof(
char *);
707 char **configVal =
g.configVals;
710 for (i = 0; i < nValidCnfgs; i++){
714 g.config_select |= 1 << i;
716 value = strpbrk(found,
"=");
719 configVal[i] = value;
722 g.config_select &= ~(1 << i);
727 for (i = 0; i < nValidCnfgs; i++){
728 if (configVal[i] != NULL){
729 value = strpbrk(configVal[i],
"\n");
767 for (
int i = 0; i < len; i++){
768 sprintf(
g.strbuf,
"%d %d\n", i-scaleZero, distrib[i]);
769 rv = write(fd,
g.strbuf, strlen(
g.strbuf));
771 sprintf(
g.logbuf,
"writeDistribution() Unable to write to %s. Error: %s\n",
distrib_file, strerror(errno));
780 if (epoch != *last_epoch ){
784 memset(distrib, 0, len *
sizeof(
int));
823 totals[j] += distrib[j][i];
827 sprintf(
g.strbuf,
"%s %d %d %d %d %d\n",
"sysDelay:", label[0], label[1], label[2], label[3], label[4]);
828 rv = write(fd,
g.strbuf, strlen(
g.strbuf));
830 sprintf(
g.logbuf,
"writeMultipleDistrib() Unable to write to %s. Error: %s\n",
distrib_file, strerror(errno));
836 sprintf(
g.strbuf,
"%s %d %d %d %d %d\n",
"totals:", totals[0], totals[1], totals[2], totals[3], totals[4]);
837 rv = write(fd,
g.strbuf, strlen(
g.strbuf));
839 sprintf(
g.logbuf,
"writeMultipleDistrib() Unable to write to %s. Error: %s\n",
distrib_file, strerror(errno));
845 for (
int i = 0; i < len; i++){
846 sprintf(
g.strbuf,
"%d %d %d %d %d %d\n", i-scaleZero, distrib[0][i], distrib[1][i], distrib[2][i], distrib[3][i], distrib[4][i]);
847 rv = write(fd,
g.strbuf, strlen(
g.strbuf));
849 sprintf(
g.logbuf,
"writeMultipleDistrib() Unable to write to %s. Error: %s\n",
distrib_file, strerror(errno));
858 if (epoch != *last_epoch ){
863 memset(distrib[i], 0, len *
sizeof(
int));
932 int fd =
open_logerr(filename, O_CREAT | O_WRONLY | O_TRUNC);
937 int j =
g.recIndex2 + i;
941 sprintf(
g.strbuf,
"%d %d %lf\n",
g.seq_numRec[j],
g.offsetRec[j],
g.freqOffsetRec2[j]);
942 int rv = write(fd,
g.strbuf, strlen(
g.strbuf));
944 sprintf(
g.logbuf,
"writeOffsets() Unable to write to %s. Error: %s\n", filename, strerror(errno));
959 int fd =
open_logerr(filename, O_CREAT | O_WRONLY | O_TRUNC);
964 int j =
g.recIndex + i;
968 sprintf(
g.strbuf,
"%ld %lf %lf\n",
g.timestampRec[j],
g.freqOffsetRec[j],
g.freqAllanDev[j]);
969 int rv = write(fd,
g.strbuf, strlen(
g.strbuf));
971 sprintf(
g.logbuf,
"writeFrequencyVars() Write to %s failed with error: %s\n", filename, strerror(errno));
993 int fd =
open_logerr(filename, O_CREAT | O_WRONLY | O_TRUNC);
999 char *filebuf =
new char[fileMaxLen];
1003 for (
int i = 0; i < len; i++){
1004 sprintf(
g.strbuf,
"%d %7.2lf\n", i - arrayZero, distrib[i]);
1005 fileLen += strlen(
g.strbuf);
1006 strcat(filebuf,
g.strbuf);
1009 int rv = write(fd, filebuf, fileLen + 1);
1011 sprintf(
g.logbuf,
"saveDoubleArray() Write to %s failed with error: %s\n", filename, strerror(errno));
1043 sprintf(
g.logbuf,
"processWriteRequest() Unable to open %s. Error: %s\n",
arrayData_file, strerror(errno));
1048 char requestStr[25];
1053 sscanf(
g.strbuf,
"%s %s", requestStr, filename);
1058 int arrayLen =
sizeof(
arrayData) /
sizeof(
struct saveFileData);
1059 for (
int i = 0; i < arrayLen; i++){
1060 if (strcmp(requestStr,
arrayData[i].label) == 0){
1061 if (strlen(filename) == 0){
1062 strcpy(filename,
arrayData[i].filename);
1102 g.doCalibration =
true;
1105 g.doCalibration =
false;
1109 g.exitOnLostPPS =
true;
1112 g.exitOnLostPPS =
false;
1124 g.doNTPsettime =
true;
1127 g.doNTPsettime =
false;
1131 g.doNTPsettime =
false;
1132 g.doSerialsettime =
true;
1135 g.doSerialsettime =
false;
1140 strcpy(
g.serialPort, sp);
1165 int rv = write(pfd,
g.strbuf, strlen(
g.strbuf) + 1);
1167 sprintf(
g.logbuf,
"writeSysDelay() Write to memory file failed with error: %s\n", strerror(errno));
1182 sprintf(
g.strbuf,
"%lf#%d\n", timestamp,
g.
seq_num);
1189 int rv = write(pfd,
g.strbuf, strlen(
g.strbuf) + 1);
1191 sprintf(
g.logbuf,
"writeTimestamp() write to assert_file failed with error: %s\n", strerror(errno));
1214 char *str = strstr(buf, token);
1216 sprintf(
g.logbuf,
"alignNumbersAfter(): token not found. Exiting.\n");
1220 str += strlen(token);
1223 if (buf[pos] !=
'-'){
1224 memmove(str + 1, str, len - pos);
1252 int alignTokens(
const char *refToken,
int offset,
const char *token,
char *buf,
int len){
1256 char *str = strstr(buf, refToken);
1258 sprintf(
g.logbuf,
"alignTokens(): refToken not found. Exiting.\n");
1262 str += strlen(refToken);
1265 str = strstr(buf, token);
1267 sprintf(
g.logbuf,
"alignTokens(): token not found. Exiting.\n");
1273 while (pos2 < pos1 + offset){
1274 memmove(str + 1, str, len - pos2);
1294 const char *timefmt =
"%F %H:%M:%S";
1298 strftime(timeStr, 30, timefmt, localtime(&
g.pps_t_sec));
1300 char *printfmt =
g.strbuf;
1303 strcpy(printfmt,
"%s.%06d %d jitter: ");
1306 strcpy(printfmt,
"%s.%06d %d *jitter: ");
1309 strcat(printfmt,
"%d freqOffset: %f avgCorrection: %f clamp: %d\n");
1311 sprintf(printStr, printfmt, timeStr,
g.pps_t_usec,
g.
seq_num,
1314 int len = strlen(printStr) + 1;
1319 len =
alignTokens(
"jitter:", 6,
"freqOffset:", printStr, len);
1327 len =
alignTokens(
"freqOffset:", 12,
"avgCorrection:", printStr, len);
1335 len =
alignTokens(
"avgCorrection:", 12,
"clamp:", printStr, len);
1351 sprintf(
g.logbuf,
"Restarting NTP\n");
1354 int rv =
sysCommand(
"service ntp restart > /run/shm/ntp-restart-msg");
1374 int fSize = strlen(fbuf);
1376 int wr = write(fd, fbuf, fSize);
1380 sprintf(
g.logbuf,
"ERROR: Write of new \"/etc/ntp.conf\" failed. Original unchanged.\n");
1389 if (errno == ENOENT){
1394 printf(
"%s",
g.logbuf);
1415 char *pHead = NULL, *pTail = NULL, *pNxt = NULL;
1420 while (strlen(pLine) > 0){
1422 while (pLine != NULL){
1425 while (pNxt[0] ==
' ' || pNxt[0] ==
'\t'){
1429 if (strncmp(pNxt, key1, strlen(key1)) == 0){
1431 pNxt += strlen(key1);
1433 while (pNxt[0] ==
' ' || pNxt[0] ==
'\t'){
1437 if (strncmp(pNxt, key2, strlen(key2)) == 0){
1438 pNxt += strlen(key2);
1440 while (pNxt[0] ==
' ' || pNxt[0] ==
'\t' || pNxt[0] ==
'\n'){
1445 memmove(pHead, pTail, strlen(pTail)+1);
1450 pLine = strchr(pLine,
'\n') + 1;
1463 struct stat stat_buf;
1466 if (
g.doNTPsettime){
1469 sprintf(
g.logbuf,
"disableNTP() Did not find NTP config file. Is NTP installed?\n");
1482 fstat(fd, &stat_buf);
1483 int sz = stat_buf.st_size;
1485 int fbufSz = sz + strlen(
"\ndisable ntp\n") + 10;
1487 char *fbuf =
new char[fbufSz];
1488 memset(fbuf, 0, fbufSz);
1491 if (rv == -1 || rv != sz){
1499 if (fbuf[sz-1] ==
'\n'){
1500 strcat(fbuf,
"disable ntp\n");
1503 strcat(fbuf,
"\ndisable ntp\n");
1506 sprintf(
g.logbuf,
"Wrote 'disable ntp' to ntp.conf.\n");
1529 struct stat stat_buf;
1532 if (
g.doNTPsettime){
1543 fstat(fd, &stat_buf);
1545 int sz = stat_buf.st_size;
1546 char *fbuf =
new char[sz+1];
1549 if (rv == -1 || rv != sz){
1585 struct stat stat_buf;
1587 const char *filename =
"/run/shm/proc_devices";
1589 int rv =
sysCommand(
"cat /proc/devices > /run/shm/proc_devices");
1599 fstat(fd, &stat_buf);
1600 int sz = stat_buf.st_size;
1602 char *fbuf =
new char[sz+1];
1616 char *pos = strstr(fbuf,
"gps-pps-io");
1618 sprintf(
g.logbuf,
"Can't find gps-pps-io in \"/run/shm/proc_devices\"\n");
1623 char *end = pos - 1;
1628 while (pos2 == pos){
1630 pos2 = strpbrk(pos,
num);
1632 strcpy(majorPos, pos2);
1641 rv =
sysCommand(
"uname -r > /run/shm/linuxVersion");
1646 int fd = open(
"/run/shm/linuxVersion", O_RDONLY);
1647 rv = read(fd, fbuf, 20);
1649 sprintf(
g.logbuf,
"getLinuxVersion() Unable to read Linux version from /run/shm/linuxVersion\n");
1669 char driverFile[100];
1671 strcpy(driverFile,
"/lib/modules/");
1673 strcat(driverFile,
"/kernel/drivers/misc/gps-pps-io.ko");
1675 int fd = open(driverFile, O_RDONLY);
1677 if (errno == ENOENT){
1678 sprintf(
g.logbuf,
"Linux version changed. Requires\n");
1679 printf(
"%s",
g.logbuf);
1681 sprintf(
g.logbuf,
"reinstall of version-matching pps-client.\n");
1682 printf(
"%s",
g.logbuf);
1689 char *insmod =
g.strbuf;
1690 strcpy(insmod,
"/sbin/insmod ");
1691 strcat(insmod, driverFile);
1692 sprintf(insmod + strlen(insmod),
" PPS_GPIO=%d OUTPUT_GPIO=%d INTRPT_GPIO=%d", ppsGPIO, outputGPIO, intrptGPIO);
1701 char *mknod =
g.strbuf;
1702 strcpy(mknod,
"mknod /dev/gps-pps-io c ");
1705 sprintf(
g.logbuf,
"driver_load() error: No major found!\n");
1710 strcat(mknod,
" 0");
1717 rv =
sysCommand(
"chgrp root /dev/gps-pps-io");
1722 rv =
sysCommand(
"chmod 664 /dev/gps-pps-io");
1752 pSpc = strpbrk((
char *)pbuf,
space);
1754 pNum = strpbrk(pSpc,
num);
1755 pSpc = strpbrk(pNum,
space);
1756 pNum = strpbrk(pSpc,
num);
1758 sscanf(pNum,
"%d ", &seqNum);
1769 struct timespec ts2;
1771 struct stat stat_buf;
1772 int seqNum, lastSeqNum = -1;
1774 int dispTime = 500000;
1776 gettimeofday(&tv1, NULL);
1784 nanosleep(&ts2, NULL);
1788 printf(
"showStatusEachSecond(): Could not open ");
1793 fstat(fd, &stat_buf);
1794 int sz = stat_buf.st_size;
1797 printf(
"showStatusEachSecond() buffer too small. sz: %d\n", sz);
1802 int rv = read(fd, paramsBuf, sz);
1805 printf(
"showStatusEachSecond() Read paramsBuf failed with error: %s\n", strerror(errno));
1811 paramsBuf[sz]=
'\0';
1813 int clen = strcspn(paramsBuf,
"0123456789");
1815 printf(
"%s", paramsBuf);
1820 if (seqNum != lastSeqNum){
1821 printf(
"%s", paramsBuf);
1823 lastSeqNum = seqNum;
1828 gettimeofday(&tv1, NULL);
1832 printf(
"Exiting PPS-Client status display\n");
1858 if (i == argc - 1 || argv[i+1][0] ==
'-'){
1859 printf(
"Error: Missing argument for %s.\n", argv[i]);
1879 printf(
"daemonSaveArray() Open arrayData_file failed\n");
1883 strcpy(buf, requestStr);
1885 if (filename != NULL){
1887 strcat(buf, filename);
1890 int rv = write(fd, buf, strlen(buf) + 1);
1893 sprintf(
g.logbuf,
"daemonSaveArray() Write to tmpfs memory file failed\n");
1905 printf(
"Accepts any of these:\n");
1906 int arrayLen =
sizeof(
arrayData) /
sizeof(
struct saveFileData);
1907 for (
int i = 0; i < arrayLen; i++){
1925 int arrayLen =
sizeof(
arrayData) /
sizeof(
struct saveFileData);
1928 for (i = 0; i < arrayLen; i++){
1929 if (strcmp(requestStr,
arrayData[i].label) == 0){
1934 printf(
"Arg \"%s\" not recognized\n", argv[i+1]);
1939 char *filename = NULL;
1940 for (
int j = 1; j < argc; j++){
1941 if (strcmp(argv[j],
"-f") == 0){
1943 printf(
"Requires a filename.\n");
1947 g.strbuf[strlen(argv[j+1])] =
'\0';
1948 filename =
g.strbuf;
1953 if (filename != NULL){
1954 printf(
"Writing to file: %s\n", filename);
1957 for (i = 0; i < arrayLen; i++){
1958 if (strcmp(requestStr,
arrayData[i].label) == 0){
1959 printf(
"Writing to default file: %s\n",
arrayData[i].filename);
1990 bool verbose =
false;
1999 printf(
"PPS-Client v%s is running.\n",
version);
2003 for (
int i = 1; i < argc; i++){
2004 if (strcmp(argv[i],
"-v") == 0){
2008 for (
int i = 1; i < argc; i++){
2009 if (strcmp(argv[i],
"-s") == 0){
2024 printf(
"Displaying second-by-second state params (ctrl-c to quit):\n");
2045 int idx = timeCorrection + len / 6;
2050 else if (idx > len){
2053 g.errorDistrib[idx] += 1;
2069 int idx = rawError + len / 6;
2074 else if (idx > len){
2077 g.jitterDistrib[idx] += 1;
2089 signal(SIGTERM, SIG_IGN);
2090 sprintf(
g.logbuf,
"Recieved SIGTERM\n");
2092 g.exit_requested =
true;
2102 signal(SIGHUP, SIG_IGN);
2117 if (
g.delayLabel[i] != 0){
2118 if (sysDelay ==
g.delayLabel[i]){
2123 g.delayLabel[i] = sysDelay;
2139 int idx = intrptDelay;
2149 g.intrptDistrib[j][idx] += 1;
2151 g.interruptCount += 1;
2168 g.sysDelayDistrib[idx] += 1;
2170 g.sysDelayCount += 1;
2189 g.freqOffsetDiff[
g.intervalCount] =
g.
freqOffset -
g.lastFreqOffset;
2192 g.intervalCount += 1;
2195 gettimeofday(&t, NULL);
2199 double diffSum = 0.0;
2201 diffSum +=
g.freqOffsetDiff[i] *
g.freqOffsetDiff[i];
2203 g.freqAllanDev[
g.recIndex] = sqrt(diffSum * norm * 0.5);
2205 g.timestampRec[
g.recIndex] = t.tv_sec;
2207 g.freqOffsetRec[
g.recIndex] =
g.freqOffsetSum * norm;
2214 g.intervalCount = 0;
2215 g.freqOffsetSum = 0.0;
2234 g.offsetRec[
g.recIndex2] = timeCorrection;
void writeToLog(char *logbuf)
void buildInterruptDistrib(int intrptDelay)
int replaceNTPConfig(const char *fbuf)
const char * log_file
Stores activity and errors.
int alignTokens(const char *refToken, int offset, const char *token, char *buf, int len)
void recordOffsets(int timeCorrection)
char * copyMajorTo(char *majorPos)
void showStatusEachSecond(void)
void recordFrequencyVars(void)
const char * distrib_file
Stores a forming distribution of offset corrections.
double freqOffset
System clock frequency correction calculated as G.integralTimeCorrection * G.integralGain.
const char * last_sysDelay_distrib_file
Stores a distribution of sysDelay.
void writeJitterDistribFile(void)
#define INTRPT_DISTRIB_LEN
void printAcceptedArgs(void)
int saveDoubleArray(double distrib[], const char *filename, int len, int arrayZero)
const char * valid_config[]
void writeTimestamp(double timestamp)
struct G g
Declares the global variables defined in pps-client.h.
const char * jitter_distrib_file
Stores a forming distribution of offset corrections.
bool configHasValue(int config_val, void *value)
#define JITTER_DISTRIB_LEN
int daemonSaveArray(const char *requestStr, const char *filename)
char linuxVersion[20]
Array for recording the Linux version.
const char * sysDelay_file
The current sysDelay value updated each second.
int alignNumbersAfter(const char *token, char *buf, int len)
const char * intrpt_distrib_file
Stores a forming distribution of offset corrections.
int getSeqNum(const char *pbuf)
int sysCommand(const char *cmd)
int read_logerr(int fd, char *buf, int sz, const char *filename)
#define RAW_ERROR_ZERO
Index corresponding to rawError == 0 in detectDelayPeak().
void buildSysDelayDistrib(int sysDelay)
double avgCorrection
A one-minute rolling average of G.timeCorrection values generated by getAverageCorrection().
int writeFileMsgToLogbuf(const char *filename, char *logbuf)
const char * ntp_config_bac
Backup of the NTP configuration file.
const char * assert_file
The timestamps of the time corrections each second.
const char * displayParams_file
Temporary file storing params for the status display.
const char * last_distrib_file
Stores the completed distribution of offset corrections.
void writeFrequencyVars(const char *filename)
char * getLinuxVersion(void)
void couldNotOpenMsgTo(char *logbuf, const char *filename)
char * getString(int key)
int accessDaemon(int argc, char *argv[])
bool configWasRead
True if pps-client.conf was read at least once.
const char * old_log_file
Stores activity and errors.
void TERMhandler(int sig)
void errorReadingMsgTo(char *logbuf, const char *filename)
void writeDistribution(int distrib[], int len, int scaleZero, int count, int *last_epoch, const char *distrib_file, const char *last_distrib_file)
bool isVerbose
Enables continuous printing of PPS-Client status params when "true".
const char * last_intrpt_distrib_file
Stores the completed distribution of offset corrections.
struct saveFileData arrayData[]
bool missingArg(int argc, char *argv[], int i)
void writeSysdelayDistribFile(void)
void buildErrorDistrib(int timeCorrection)
const char * ntp_config_file
The NTP configuration file.
int getDriverGPIOvals(void)
const char * pidFilename
Stores the PID of PPS-Client.
int getDelayIndex(int sysDelay)
void writeOffsets(const char *filename)
void writeIntrptDistribFile(void)
bool hasString(int key, const char *string)
#define ERROR_DISTRIB_LEN
#define NUM_5_MIN_INTERVALS
Number of five minute intervals in 24 hours.
const char * ntp_config_part
Temporary filename for an NTP config file during copy.
int sysDelayShift
Assigned from G.delayShift and subtracted from G.rawError in correctDelayPeak() when a delay shift oc...
int processWriteRequest(void)
int bufferStateParams(void)
unsigned int seq_num
Advancing count of the number of PPS interrupt timings that have been received.
int writeFileMsgToLog(const char *filename)
double rawErrorDistrib[ERROR_DISTRIB_LEN]
The distribution used to detect a delay shift in detectDelayPeak().
void writeMultipleDistrib(int label[], int distrib[][INTRPT_DISTRIB_LEN], int len, int scaleZero, int count, int *last_epoch, const char *distrib_file, const char *last_distrib_file)
#define SETTLE_TIME
The PPS-Client up time required before saving performance data.
const char * arrayData_file
Stores a request sent to the PPS-Client daemon.
Struct for program-wide global variables showing those important to the controller.
const char * sysDelay_distrib_file
Stores a forming distribution of sysDelay values.
int outputGPIO
The calibrate GPIO output number read from pps-client.conf and passed to the driver.
void writeToLogNoTimestamp(char *logbuf)
void removeConfigKeys(const char *key1, const char *key2, char *fbuf)
int open_logerr(const char *filename, int flags)
int interruptLossCount
Records the number of consecutive lost PPS interrupt times.
#define INTERRUPT_DISTRIB
const char * config_file
The PPS-Client configuration file.
int hardLimit
An adaptive limit value determined by setHardLimit() and applied to G.rawError by clampJitter() as th...
void buildJitterDistrib(int rawError)
#define FREQDIFF_INTRVL
The number of minutes between Allan deviation samples of system clock frequency correction.
struct timespec setSyncDelay(int timeAt, int fracSec)
int writeStatusStrings(void)
int parseSaveDataRequest(int argc, char *argv[], const char *requestStr)
int intrptGPIO
The calibrate GPIO interrupt number read from pps-client.conf and passed to the driver.
int driver_load(int ppsGPIO, int outputGPIO, int intrptGPIO)
void writeErrorDistribFile(void)
int ppsGPIO
The PPS GPIO interrupt number read from pps-client.conf and passed to the driver. ...
const char * version
Program version 1.4.0 created on 17 Dec 2017.
void bufferStatusMsg(const char *msg)
void initFileLocalData(void)
const char * last_jitter_distrib_file
Stores the completed distribution of offset corrections.