46
46
static pid_t parent ;
47
47
48
48
49
+ static char JsonBuffer [8192 ];
50
+
49
51
static void hc_background (int fd , int mode ) {
50
52
if (kill (parent , 0 ) < 0 ) exit (0 );
51
53
}
52
54
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
+
53
61
static const char * hc_http_status (const char * method , const char * uri ,
54
62
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 ;
61
65
char latitude [20 ];
62
66
char longitude [20 ];
63
67
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 "" ;
70
71
if (hc_db_get_count (HC_NMEA_STATUS ) != 1
71
72
|| hc_db_get_size (HC_NMEA_STATUS ) != sizeof (hc_nmea_status )) {
72
73
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,
75
76
}
76
77
}
77
78
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 )) {
86
84
fprintf (stderr , "wrong data structure for table %s\n" ,
87
- HC_CLOCK_DRIFT );
85
+ HC_CLOCK_STATUS );
88
86
exit (1 );
89
87
}
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 );
102
88
}
103
89
104
90
// This conversion is not made when decoding the NMEA stream to avoid
105
91
// consuming CPU in the high-priority time synchronization process.
106
92
//
107
93
hc_nmea_convert (latitude , sizeof (latitude ),
108
- status_db -> latitude , status_db -> hemisphere [0 ]);
94
+ nmea_db -> latitude , nmea_db -> hemisphere [0 ]);
109
95
hc_nmea_convert (longitude , sizeof (longitude ),
110
- status_db -> longitude , status_db -> hemisphere [1 ]);
96
+ nmea_db -> longitude , nmea_db -> hemisphere [1 ]);
111
97
112
- snprintf (buffer , sizeof (buffer ),
98
+ snprintf (JsonBuffer , sizeof (JsonBuffer ),
113
99
"{\"gps\":{\"fix\":%s"
114
100
",\"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 ],
124
111
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" , "]}}" );
128
149
echttp_content_type_json ();
129
- return buffer ;
150
+ return JsonBuffer ;
130
151
}
131
152
132
153
void hc_http (int argc , const char * * argv ) {
133
154
parent = getppid ();
134
155
if (echttp_open (argc , argv ) <= 0 ) exit (1 );
135
156
136
157
echttp_route_uri ("/status" , hc_http_status );
158
+ echttp_route_uri ("/clock/drift" , hc_http_clockdrift );
137
159
echttp_static_route ("/ui" , "/usr/local/lib/houseclock/public" );
138
160
echttp_background (& hc_background );
139
161
echttp_loop ();
0 commit comments