Skip to content

Commit c8caf2a

Browse files
Add clock status information, separate current status and drift history
1 parent 45c2f3a commit c8caf2a

File tree

3 files changed

+97
-49
lines changed

3 files changed

+97
-49
lines changed

hc_clock.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ static int clockShowDrift = 0;
6363

6464
static int clockSynchronized = 0;
6565

66+
static hc_clock_status *hc_clock_status_db = 0;
6667
static int *hc_clock_drift_db = 0;
6768

6869
const char *hc_clock_help (int level) {
@@ -98,6 +99,17 @@ void hc_clock_initialize (int argc, const char **argv) {
9899
}
99100
hc_clock_drift_db = (int *) hc_db_get (HC_CLOCK_DRIFT);
100101
for (i = 0; i < 120; ++i) hc_clock_drift_db[i] = 0;
102+
103+
i = hc_db_new (HC_CLOCK_STATUS, sizeof(hc_clock_status), 1);
104+
if (i != 0) {
105+
fprintf (stderr,
106+
"cannot create %s: %s\n", HC_CLOCK_STATUS, strerror(i));
107+
exit (1);
108+
}
109+
hc_clock_status_db = (hc_clock_status *)hc_db_get (HC_CLOCK_STATUS);
110+
hc_clock_status_db->synchronized = 0;
111+
hc_clock_status_db->precision = clockPrecision;
112+
hc_clock_status_db->drift = 0;
101113
}
102114

103115
void hc_clock_synchronize(const struct timeval *gps,
@@ -109,6 +121,10 @@ void hc_clock_synchronize(const struct timeval *gps,
109121
time_t absdrift = (drift < 0)? (0 - drift) : drift;
110122

111123
if (hc_clock_drift_db) hc_clock_drift_db[local->tv_sec%120] = (int)drift;
124+
if (hc_clock_status_db) {
125+
hc_clock_status_db->drift = (int)drift;
126+
hc_clock_status_db->timestamp = *local;
127+
}
112128

113129
if (clockShowDrift || hc_test_mode()) {
114130
printf ("[%d]=%8.3f\n", local->tv_sec%120, drift/1000.0);
@@ -117,6 +133,7 @@ void hc_clock_synchronize(const struct timeval *gps,
117133

118134
if (absdrift < clockPrecision) {
119135
clockSynchronized = 1;
136+
if (hc_clock_status_db) hc_clock_status_db->synchronized = 1;
120137
return;
121138
}
122139

hc_clock.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,12 @@ int hc_clock_synchronized (void);
3131
*/
3232
#define HC_CLOCK_DRIFT "ClockDrift"
3333

34+
#define HC_CLOCK_STATUS "ClockStatus"
35+
36+
typedef struct {
37+
int synchronized;
38+
int precision;
39+
int drift;
40+
struct timeval timestamp;
41+
} hc_clock_status;
42+

hc_http.c

Lines changed: 71 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -46,27 +46,28 @@
4646
static pid_t parent;
4747

4848

49+
static char JsonBuffer[8192];
50+
4951
static void hc_background (int fd, int mode) {
5052
if (kill (parent, 0) < 0) exit(0);
5153
}
5254

55+
static void *hc_http_attach (const char *name) {
56+
void *p = hc_db_get (name);
57+
if (p == 0) echttp_error (503, "Service Temporarily Unavailable");
58+
return p;
59+
}
60+
5361
static const char *hc_http_status (const char *method, const char *uri,
5462
const char *data, int length) {
55-
static char buffer[8192];
56-
static char *driftbuffer;
57-
static int driftbuffersize;
58-
static hc_nmea_status *status_db = 0;
59-
static int *drift_db = 0;
60-
static int drift_count;
63+
static hc_nmea_status *nmea_db = 0;
64+
static hc_clock_status *clock_db = 0;
6165
char latitude[20];
6266
char longitude[20];
6367

64-
if (status_db == 0) {
65-
status_db = (hc_nmea_status *) hc_db_get (HC_NMEA_STATUS);
66-
if (status_db == 0) {
67-
echttp_error (503, "Service Temporarily Unavailable");
68-
return "";
69-
}
68+
if (nmea_db == 0) {
69+
nmea_db = (hc_nmea_status *) hc_http_attach (HC_NMEA_STATUS);
70+
if (nmea_db == 0) return "";
7071
if (hc_db_get_count (HC_NMEA_STATUS) != 1
7172
|| hc_db_get_size (HC_NMEA_STATUS) != sizeof(hc_nmea_status)) {
7273
fprintf (stderr, "wrong data structure for table %s\n",
@@ -75,65 +76,86 @@ static const char *hc_http_status (const char *method, const char *uri,
7576
}
7677
}
7778

78-
if (drift_db == 0) {
79-
drift_db = (int *) hc_db_get (HC_CLOCK_DRIFT);
80-
if (drift_db == 0) {
81-
echttp_error (503, "Service Temporarily Unavailable");
82-
return "";
83-
}
84-
drift_count = hc_db_get_count (HC_CLOCK_DRIFT);
85-
if (hc_db_get_size (HC_CLOCK_DRIFT) != sizeof(int)) {
79+
if (clock_db == 0) {
80+
clock_db = (hc_clock_status *) hc_http_attach (HC_CLOCK_STATUS);
81+
if (clock_db == 0) return "";
82+
if (hc_db_get_count (HC_CLOCK_STATUS) != 1
83+
|| hc_db_get_size (HC_CLOCK_STATUS) != sizeof(hc_clock_status)) {
8684
fprintf (stderr, "wrong data structure for table %s\n",
87-
HC_CLOCK_DRIFT);
85+
HC_CLOCK_STATUS);
8886
exit (1);
8987
}
90-
driftbuffersize = drift_count * 12;
91-
driftbuffer = malloc(driftbuffersize);
92-
}
93-
94-
snprintf (driftbuffer, driftbuffersize, "%d", drift_db[0]);
95-
int room = driftbuffersize - strlen(driftbuffer);
96-
char *p = driftbuffer + (driftbuffersize-room);
97-
int i;
98-
for (i = 1; i < drift_count; ++i) {
99-
snprintf (p, room, ",%d", drift_db[i]);
100-
room -= strlen(p);
101-
p = driftbuffer + (driftbuffersize-room);
10288
}
10389

10490
// This conversion is not made when decoding the NMEA stream to avoid
10591
// consuming CPU in the high-priority time synchronization process.
10692
//
10793
hc_nmea_convert (latitude, sizeof(latitude),
108-
status_db->latitude, status_db->hemisphere[0]);
94+
nmea_db->latitude, nmea_db->hemisphere[0]);
10995
hc_nmea_convert (longitude, sizeof(longitude),
110-
status_db->longitude, status_db->hemisphere[1]);
96+
nmea_db->longitude, nmea_db->hemisphere[1]);
11197

112-
snprintf (buffer, sizeof(buffer),
98+
snprintf (JsonBuffer, sizeof(JsonBuffer),
11399
"{\"gps\":{\"fix\":%s"
114100
",\"time\":[%c%c,%c%c,%c%c],\"date\":[%d,%c%c,%c%c]"
115-
",\"latitude\":%s,\"longitude\":%s,\"timestamp\":%zd.%03d}"
116-
",\"clock\":{\"drift\":[%s]}}",
117-
status_db->fix?"true":"false",
118-
status_db->time[0], status_db->time[1],
119-
status_db->time[2], status_db->time[3],
120-
status_db->time[4], status_db->time[5],
121-
2000 + (status_db->date[4]-'0')*10 + (status_db->date[5]-'0'),
122-
status_db->date[2], status_db->date[3],
123-
status_db->date[0], status_db->date[1],
101+
",\"latitude\":%s,\"longitude\":%s}"
102+
",\"clock\":{\"synchronized\":%s"
103+
",\"precision\":%d,\"drift\":%d,\"timestamp\":%zd.%03d}}",
104+
nmea_db->fix?"true":"false",
105+
nmea_db->time[0], nmea_db->time[1],
106+
nmea_db->time[2], nmea_db->time[3],
107+
nmea_db->time[4], nmea_db->time[5],
108+
2000 + (nmea_db->date[4]-'0')*10 + (nmea_db->date[5]-'0'),
109+
nmea_db->date[2], nmea_db->date[3],
110+
nmea_db->date[0], nmea_db->date[1],
124111
latitude, longitude,
125-
(size_t) (status_db->timestamp.tv_sec),
126-
status_db->timestamp.tv_usec/1000,
127-
driftbuffer);
112+
clock_db->synchronized?"true":"false",
113+
clock_db->precision,
114+
clock_db->drift,
115+
(size_t) (clock_db->timestamp.tv_sec),
116+
clock_db->timestamp.tv_usec/1000);
117+
echttp_content_type_json();
118+
return JsonBuffer;
119+
}
120+
121+
static const char *hc_http_clockdrift (const char *method, const char *uri,
122+
const char *data, int length) {
123+
static int *drift_db = 0;
124+
static int drift_count;
125+
126+
if (drift_db == 0) {
127+
drift_db = (int *) hc_http_attach (HC_CLOCK_DRIFT);
128+
if (drift_db == 0) return "";
129+
drift_count = hc_db_get_count (HC_CLOCK_DRIFT);
130+
if (hc_db_get_size (HC_CLOCK_DRIFT) != sizeof(int)) {
131+
fprintf (stderr, "wrong data structure for table %s\n",
132+
HC_CLOCK_DRIFT);
133+
exit (1);
134+
}
135+
}
136+
137+
snprintf (JsonBuffer, sizeof(JsonBuffer),
138+
"{\"clock\":{\"drift\":[%d", drift_db[0]);
139+
140+
int room = sizeof(JsonBuffer) - strlen(JsonBuffer);
141+
char *p = JsonBuffer + (sizeof(JsonBuffer)-room);
142+
int i;
143+
for (i = 1; i < drift_count; ++i) {
144+
snprintf (p, room, ",%d", drift_db[i]);
145+
room -= strlen(p);
146+
p = JsonBuffer + (sizeof(JsonBuffer)-room);
147+
}
148+
snprintf (p, room, "%s", "]}}");
128149
echttp_content_type_json();
129-
return buffer;
150+
return JsonBuffer;
130151
}
131152

132153
void hc_http (int argc, const char **argv) {
133154
parent = getppid();
134155
if (echttp_open (argc, argv) <= 0) exit(1);
135156

136157
echttp_route_uri ("/status", hc_http_status);
158+
echttp_route_uri ("/clock/drift", hc_http_clockdrift);
137159
echttp_static_route ("/ui", "/usr/local/lib/houseclock/public");
138160
echttp_background (&hc_background);
139161
echttp_loop();

0 commit comments

Comments
 (0)