22 #include "../client/pps-client.h" 29 static struct sntpLocalVars {
36 bool allServersQueried;
37 unsigned int lastServerUpdate;
40 const char*
srv0 =
"0.debian.pool.ntp.org";
41 const char*
srv1 =
"1.debian.pool.ntp.org";
42 const char*
srv2 =
"2.debian.pool.ntp.org";
43 const char*
srv3 =
"3.debian.pool.ntp.org";
60 if (tcp->
buf != NULL){
66 buflen += strlen(
srv0) + 1;
67 buflen += strlen(
srv1) + 1;
68 buflen += strlen(
srv2) + 1;
69 buflen += strlen(
srv3) + 1;
73 tcp->
buf =
new char[buflen];
75 char *bufptr = tcp->
buf;
77 f.ntp_server[0] = bufptr;
79 bufptr += strlen(
srv0) + 1;
81 f.ntp_server[1] = bufptr;
83 bufptr += strlen(
srv1) + 1;
85 f.ntp_server[2] = bufptr;
87 bufptr += strlen(
srv2) + 1;
89 f.ntp_server[3] = bufptr;
92 f.serverTimeDiff[i] = 1000000;
93 f.threadIsBusy[i] =
false;
100 time_t t = time(NULL);
101 struct tm *tmp = localtime(&t);
102 strftime(timestamp,
STRBUF_SZ,
"%F %H:%M:%S ", tmp);
103 strcat(logbuf, timestamp);
119 time_t
getServerTime(
const char *server,
int id,
char *strbuf,
char *logbuf){
120 struct timeval startTime, returnTime;
121 struct stat stat_buf;
130 const char *filename =
"/run/shm/sntp_out";
131 sprintf(
num,
"%d",
id);
134 strcpy(cmd,
"sntp ");
137 strcat(cmd, filename);
140 gettimeofday(&startTime, NULL);
145 gettimeofday(&returnTime, NULL);
147 if (returnTime.tv_sec - startTime.tv_sec > 0){
149 sprintf(buf,
"Skipped server %d. Took more than 1 second to respond.\n",
id);
155 strcpy(fname, filename);
158 int fd = open((
const char *)fname, O_RDONLY);
160 strcpy(buf,
"ERROR: could not open \"");
167 fstat(fd, &stat_buf);
168 int sz = stat_buf.st_size;
171 rv = read(fd, strbuf, sz);
173 strcpy(buf,
"ERROR: reading \"");
174 strcat(buf, filename);
175 strcat(buf,
"\" was interrupted.\n");
190 for (i = 0; i < sz; i++){
191 if (strbuf[i] ==
'\n'){
196 char *pLine = strbuf + i;
198 if (pLine[4] !=
'-' || pLine[7] !=
'-'){
200 sprintf(buf,
"SNTP server %d returned an error message:\n",
id);
207 end = strstr(pLine,
"+/-");
215 memset(&tm, 0,
sizeof(
struct tm));
218 sscanf(pLine,
"%4d-%2d-%2d %2d:%2d:%2d.%6d (%5d) %f",
219 &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
220 &tm.tm_hour, &tm.tm_min, &tm.tm_sec,
221 &fracSec, &tz, &delta);
223 return (
int)floor(delta);
245 time_t timeDiff =
getServerTime(ntp_server, i, strbuf, logbuf);
267 int nServersReporting = 0;
272 for (
int j = 0; j < f.numServers; j++){
273 if (f.serverTimeDiff[j] != 1000000){
275 for (k = 0; k < f.numServers; k++){
276 if (f.serverTimeDiff[j] == diff[k]){
281 if (k == f.numServers){
282 for (
int m = 0; m < f.numServers; m++){
284 diff[m] = f.serverTimeDiff[j];
290 nServersReporting += 1;
295 int maxHitsIndex = 0;
297 for (
int j = 0; j < f.numServers; j++){
298 if (count[j] > maxHits){
305 sprintf(
g.msgbuf,
"Number of servers responding: %d\n", nServersReporting);
309 f.serverTimeDiff[i] = 1000000;
311 return nServersReporting;
325 for (
int i = 0; i < numServers; i++){
328 if (strlen(logbuf) > 0){
344 if (f.allServersQueried){
345 if (
g.queryCount == 0){
346 f.allServersQueried =
false;
351 if (
g.queryCount > 0){
364 if (f.numServers == -1){
365 sprintf(
g.logbuf,
"Unable to allocate the SNTP servers!\n");
372 f.timeCheckEnable = f.numServers;
377 if (f.timeCheckEnable > 0){
381 f.timeCheckEnable -= 1;
386 f.allServersQueried =
true;
390 if (f.threadIsBusy[idx]){
391 sprintf(
g.msgbuf,
"Server %d is busy.\n", idx);
395 sprintf(
g.msgbuf,
"Requesting time from Server %d\n", idx);
398 rv = pthread_create(&((tcp->
tid)[idx]), &(tcp->
attr), (
void* (*)(
void*))&
doTimeCheck, tcp);
400 sprintf(
g.logbuf,
"Can't create thread : %s\n", strerror(errno));
417 memset(&f, 0,
sizeof(
struct sntpLocalVars));
427 int rv = pthread_attr_init(&(tcp->
attr));
429 sprintf(
g.logbuf,
"Can't init pthread_attr_t object: %s\n", strerror(errno));
436 sprintf(
g.logbuf,
"Can't set pthread_attr_setstacksize(): %s\n", strerror(errno));
441 rv = pthread_attr_setdetachstate(&(tcp->
attr), PTHREAD_CREATE_DETACHED);
443 sprintf(
g.logbuf,
"Can't set pthread_attr_t object state: %s\n", strerror(errno));
457 pthread_attr_destroy(&(tcp->
attr));
460 if (tcp->
buf != NULL){
void writeToLog(char *logbuf)
char * logbuf
Space for returned log messages.
void doTimeCheck(timeCheckParams *tcp)
#define PTHREAD_STACK_REQUIRED
Stack space requirements for threads.
void freeSNTPThreads(timeCheckParams *tcp)
#define CHECK_TIME
Interval between Internet time checks (about 17 minutes)
void makeSNTPTimeQuery(timeCheckParams *tcp)
int serverIndex
Identifying index from the list of active SNTP servers.
int sysCommand(const char *cmd)
int writeFileMsgToLogbuf(const char *filename, char *logbuf)
char * strbuf
Space for messages and query strings.
int consensusTimeError
Consensus value of whole-second time corrections for DST or leap seconds from Internet SNTP servers...
int * serverTimeDiff
Time difference between local time and server time.
void updateLog(char *buf, int numServers)
int getTimeConsensusAndCount(void)
#define MAX_SERVERS
Maximum number of SNTP time servers to use.
struct G g
Declares the global variables defined in pps-client.h.
pthread_attr_t attr
Thread attribute object.
unsigned int seq_num
Advancing count of the number of PPS interrupt timings that have been received.
int allocNTPServerList(timeCheckParams *tcp)
time_t getServerTime(const char *server, int id, char *strbuf, char *logbuf)
Struct for passing arguments to and from threads querying SNTP time servers or GPS receivers...
bool * threadIsBusy
True while thread is waiting for or processing a time query.
Struct for program-wide global variables showing those important to the controller.
void writeToLogNoTimestamp(char *logbuf)
int allocInitializeSNTPThreads(timeCheckParams *tcp)
void copyToLog(char *logbuf, const char *msg)
char * buf
Space for the active SNTP server list.
char ** ntp_server
The active SNTP server list when SNTP is used.
void bufferStatusMsg(const char *msg)
pthread_t * tid
Thread id.