22 #include "../client/pps-client.h" 28 static struct serialLocalVars {
29 int serverTimeDiff[1];
33 bool allServersQueried;
34 unsigned int lastServerUpdate;
40 int lastSerialTimeDif;
61 memset(scnbuf, 0, 10);
64 memset(&gmt, 0,
sizeof(
struct tm));
66 char *active, *ctmp2, *ctmp4;
72 float ftmp1, ftmp3, ftmp5, ftmp6;
75 char *pstr = strstr((
char *)msgbuf,
"$GPRMC");
77 char *end = pstr + 64;
78 char *pNext = strstr(pstr + 10,
"$");
81 sscanf(pstr,
"$GPRMC,%2d%2d%2d.%d,%1c,%f,%1c,%f,%1c,%f,%f,%2d%2d%2d,", &gmt.tm_hour, &gmt.tm_min, &gmt.tm_sec,
82 &frac, active, &ftmp1, ctmp2, &ftmp3, ctmp4, &ftmp5, &ftmp6, &gmt.tm_mday, &gmt.tm_mon, &gmt.tm_year);
84 if (active[0] ==
'A'){
87 *gmtSeconds = mktime(&gmt);
92 sprintf(tcp->
strbuf,
"getUTCfromGPSmessages() A GPS message was received but it is not active.\n");
95 if (f.lostGPSCount == 0) {
100 if (f.lostGPSCount == 5){
101 sprintf(tcp->
strbuf,
"getUTCfromGPSmessages() Unable to connect to GPS. Will retry in %d minutes.\n",
CHECK_TIME_SERIAL / 60);
148 sprintf(tcp->
strbuf,
"waitForGPSmessages() Unable to open %s\n", tcp->
serialPort);
162 int rv = select(rfd + 1, &rfds, NULL, NULL, &wait);
164 sprintf(tcp->
strbuf,
"waitForGPSmessages() select failed with error %s.\n", strerror(errno));
170 sprintf(tcp->
strbuf,
"waitForGPSmessages() No messages were available within one second.\n");
177 time_t clkSeconds = time(0);
178 struct tm *gmt = gmtime(&clkSeconds);
179 *gmtSeconds = mktime(gmt);
181 gettimeofday(t_gmt, NULL);
185 slp.tv_nsec = 250000000;
187 nanosleep(&slp, NULL);
191 int nchars = read(rfd, msgbuf, 250);
193 sprintf(tcp->
strbuf,
"waitForGPSmessages() read on serial port received empty buffer.\n");
228 time_t difSeconds = 0, gmt0Seconds = 0, gmtSeconds;
231 memset(msgbuf, 0, 300 *
sizeof(
char));
233 struct timeval t_gmt, t_rdy;
236 if (rv == 0 || rv == -1){
244 gettimeofday(&t_rdy, NULL);
246 bool finishedInSameSecond = (t_gmt.tv_sec == t_rdy.tv_sec);
247 if (finishedInSameSecond){
248 difSeconds = gmt0Seconds - gmtSeconds;
249 *timeDif = (int)difSeconds;
253 sprintf(tcp->
strbuf,
"getTimeOffsetOverSerial() Discarded the data. Took over 1 second. OS latency!\n");
287 if (f.lastSerialTimeDif != 0){
288 sprintf(tcp->
strbuf,
"doSerialTimeCheck() No timeDif on second read. First read was GPS error.\n");
294 f.lastSerialTimeDif = 0;
299 if (timeDif != 0 && f.lastSerialTimeDif == 0){
300 sprintf(tcp->
strbuf,
"doSerialTimeCheck() timeDif detected on first read: %d\n", timeDif);
304 f.lastSerialTimeDif = timeDif;
309 if (timeDif != 0 && f.lastSerialTimeDif != 0){
310 if (timeDif == f.lastSerialTimeDif ){
311 sprintf(tcp->
strbuf,
"doSerialTimeCheck() Verified timeDif on second read: %d\n", timeDif);
317 f.lastSerialTimeDif = 0;
323 sprintf(tcp->
strbuf,
"doSerialTimeCheck() Second timeDif read: %d does not match the first: %d. Not valid.\n", timeDif, f.lastSerialTimeDif);
329 f.lastSerialTimeDif = 0;
336 else if (isValidDif == 0){
337 sprintf(tcp->
strbuf,
"doSerialTimeCheck() Did not see a GPRMC message. Retrying.\n");
341 else if (isValidDif == -1){
372 sprintf(tcp->
strbuf,
"Time check failed with an error. See the pps-client.log\n");
388 sprintf(
g.msgbuf,
"Thread is busy.\n");
395 f.doReadSerial =
true;
397 sprintf(
g.logbuf,
"Requesting a GPS time check.\n");
406 sprintf(
g.logbuf,
"Can't create thread : %s\n", strerror(errno));
424 memset(&f, 0,
sizeof(
struct serialLocalVars));
426 int buflen = strlen(
g.serialPort);
427 f.serialPort =
new char[buflen + 1];
428 strcpy(f.serialPort,
g.serialPort);
430 f.serverTimeDiff[0] = 0;
431 f.threadIsBusy[0] =
false;
439 printf(
"allocInitializeSerialThread() tcp->serialPort: %s\n", tcp->
serialPort);
444 int rv = pthread_attr_init(&(tcp->
attr));
446 sprintf(
g.logbuf,
"Can't init pthread_attr_t object: %s\n", strerror(errno));
453 sprintf(
g.logbuf,
"Can't set pthread_attr_setstacksize(): %s\n", strerror(errno));
458 rv = pthread_attr_setdetachstate(&(tcp->
attr), PTHREAD_CREATE_DETACHED);
460 sprintf(
g.logbuf,
"Can't set pthread_attr_t object state: %s\n", strerror(errno));
474 pthread_attr_destroy(&(tcp->
attr));
void writeToLog(char *logbuf)
bool doReadSerial
Flag to read serial messages from serial port.
#define PTHREAD_STACK_REQUIRED
Stack space requirements for threads.
#define CHECK_TIME_SERIAL
Interval between serial port time checks (about 10 minutes)
char * strbuf
Space for messages and query strings.
int rv
Return value of thread.
bool getUTCfromGPSmessages(const char *msgbuf, timeCheckParams *tcp, time_t *gmtSeconds)
int * serverTimeDiff
Time difference between local time and server time.
int allocInitializeSerialThread(timeCheckParams *tcp)
void freeSerialThread(timeCheckParams *tcp)
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.
char * serialPort
The serial port filename when serial time is used.
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.
int getTimeOffsetOverSerial(int *timeDif, timeCheckParams *tcp)
int makeSerialTimeQuery(timeCheckParams *tcp)
#define BLOCK_FOR_3
Blocks detection of external system clock changes for 3 seconds.
void bufferStatusMsg(const char *msg)
int waitForGPSmessages(char *msgbuf, timeCheckParams *tcp, struct timeval *t_gmt, time_t *gmtSeconds)
void doSerialTimeCheck(timeCheckParams *tcp)
pthread_t * tid
Thread id.