2 * OnCore object for the GPS packet monitor.
4 * This file is Copyright (c) 2010 by the GPSD project
5 * BSD terms apply: see the file COPYING in the distribution root for details.
14 #endif /* S_SPLINT_S */
19 #include "gpsd_config.h"
25 #endif /* HAVE_NCURSES_H */
31 #if defined(ONCORE_ENABLE) && defined(BINARY_ENABLE)
32 extern const struct gps_type_t oncore_binary;
34 static WINDOW *Ea1win, *Eawin, *Bbwin, *Enwin, *Bowin, *Aywin, *Aswin, *Atwin;
35 static unsigned char EaSVlines[8];
37 static const char *antenna[] = {
44 static const char *sv_mode[] = {
56 static const char *pps_ctrl[] = {
63 static const char *pps_sync[] = {
68 static const char *traim_sol[] = {
74 static const char *traim_status[] = {
80 static const char *pos_hold_mode[] = {
86 #define ONCTYPE(id2,id3) ((((unsigned int)id2)<<8)|(id3))
88 #define MAXTRACKSATS 8 /* the most satellites being tracked */
89 #define MAXVISSATS 12 /* the most satellites with known az/el */
91 static bool oncore_initialize(void)
96 Ea1win = subwin(devicewin, 5, 80, 1, 0);
97 Eawin = subwin(devicewin, MAXTRACKSATS + 3, 27, 6, 0);
98 Bbwin = subwin(devicewin, MAXVISSATS + 3, 22, 6, 28);
99 Enwin = subwin(devicewin, 10, 29, 6, 51);
100 Bowin = subwin(devicewin, 4, 11, 17, 0);
101 Aywin = subwin(devicewin, 4, 15, 17, 12);
102 Atwin = subwin(devicewin, 5, 9, 16, 51);
103 Aswin = subwin(devicewin, 5, 19, 16, 61);
106 if (Ea1win == NULL || Eawin == NULL || Bbwin == NULL || Enwin == NULL
107 || Bowin == NULL || Aswin == NULL || Atwin == NULL)
110 (void)syncok(Ea1win, true);
111 (void)syncok(Eawin, true);
112 (void)syncok(Bbwin, true);
113 (void)syncok(Enwin, true);
114 (void)syncok(Bowin, true);
115 (void)syncok(Aywin, true);
116 (void)syncok(Aswin, true);
117 (void)syncok(Atwin, true);
119 (void)wborder(Ea1win, 0, 0, 0, 0, 0, 0, 0, 0),
120 (void)wattrset(Ea1win, A_BOLD);
121 (void)mvwaddstr(Ea1win, 1, 1,
123 (void)mvwaddstr(Ea1win, 2, 1,
124 "Antenna: DOP: Speed: Course:");
125 (void)mvwaddstr(Ea1win, 3, 1,
126 "SV/vis: Status: Alt:");
127 (void)mvwprintw(Ea1win, 4, 4, " @@Ea (pos) ");
128 (void)wattrset(Ea1win, A_NORMAL);
130 (void)wborder(Eawin, 0, 0, 0, 0, 0, 0, 0, 0),
131 (void)wattrset(Eawin, A_BOLD);
132 (void)mvwprintw(Eawin, 1, 1, "Ch PRN mode S/N ????????");
133 (void)mvwprintw(Eawin, 10, 4, " @@Ea (sat) ");
134 for (i = 0; i < 8; i++) {
135 (void)mvwprintw(Eawin, (int)(i + 2), 1, "%2d", i);
137 (void)wattrset(Eawin, A_NORMAL);
139 (void)wborder(Bbwin, 0, 0, 0, 0, 0, 0, 0, 0),
140 (void)wattrset(Bbwin, A_BOLD);
141 (void)mvwprintw(Bbwin, 1, 1, "PRN Az El doppl ??");
142 (void)mvwprintw(Bbwin, 14, 4, " @@Bb ");
143 (void)wattrset(Bbwin, A_NORMAL);
145 (void)wborder(Enwin, 0, 0, 0, 0, 0, 0, 0, 0),
146 (void)wattrset(Enwin, A_BOLD);
147 (void)mvwprintw(Enwin, 1, 1, "Time RAIM: ");
148 (void)mvwprintw(Enwin, 2, 1, "Alarm limit:");
149 (void)mvwprintw(Enwin, 3, 1, "PPS ctrl:");
150 (void)mvwprintw(Enwin, 4, 1, "Pulse:");
151 (void)mvwprintw(Enwin, 5, 1, "PPS sync:");
152 (void)mvwprintw(Enwin, 6, 1, "TRAIM sol stat:");
153 (void)mvwprintw(Enwin, 7, 1, "Status:");
154 (void)mvwprintw(Enwin, 8, 1, "Time sol sigma:");
155 (void)mvwprintw(Enwin, 9, 4, " @@En ");
156 (void)wattrset(Enwin, A_NORMAL);
158 (void)wborder(Bowin, 0, 0, 0, 0, 0, 0, 0, 0),
159 (void)wattrset(Bowin, A_BOLD);
160 (void)mvwprintw(Bowin, 1, 1, "UTC:");
161 (void)mvwprintw(Bowin, 3, 2, " @@Bo ");
162 (void)wattrset(Bowin, A_NORMAL);
164 (void)wborder(Aywin, 0, 0, 0, 0, 0, 0, 0, 0),
165 (void)wattrset(Aywin, A_BOLD);
166 (void)mvwprintw(Aywin, 1, 1, "PPS delay:");
167 (void)mvwprintw(Aywin, 3, 4, " @@Ay ");
168 (void)wattrset(Aywin, A_NORMAL);
170 (void)wborder(Atwin, 0, 0, 0, 0, 0, 0, 0, 0),
171 (void)wattrset(Atwin, A_BOLD);
172 (void)mvwprintw(Atwin, 1, 1, "PHold:");
173 (void)mvwprintw(Atwin, 4, 1, " @@At ");
174 (void)wattrset(Atwin, A_NORMAL);
176 (void)wborder(Aswin, 0, 0, 0, 0, 0, 0, 0, 0),
177 (void)wattrset(Aswin, A_BOLD);
178 (void)mvwprintw(Aswin, 1, 1, "Lat:");
179 (void)mvwprintw(Aswin, 2, 1, "Lon:");
180 (void)mvwprintw(Aswin, 3, 1, "Alt:");
181 (void)mvwprintw(Aswin, 4, 4, " @@As ");
182 (void)wattrset(Aswin, A_NORMAL);
184 memset(EaSVlines, 0, sizeof(EaSVlines));
189 static void oncore_update(void)
191 unsigned int i, j, off;
195 assert(Eawin != NULL);
196 buf = session.packet.outbuffer;
197 type = ONCTYPE(buf[2], buf[3]);
199 case ONCTYPE('E', 'a'):
201 double lat, lon, alt;
205 unsigned char mon, day, hour, min, sec;
207 unsigned char dopt, nvis, nsat, status;
208 char statusbuf[64]; /* 6+9+3+3+10+5+7+12+1=56 */
210 mon = (unsigned char)getub(buf, 4);
211 day = (unsigned char)getub(buf, 5);
212 year = (unsigned short)getbeuw(buf, 6);
213 hour = (unsigned char)getub(buf, 8);
214 min = (unsigned char)getub(buf, 9);
215 sec = (unsigned char)getub(buf, 10);
216 nsec = (unsigned int)getbeul(buf, 11);
218 lat = getbesl(buf, 15) / 3600000.0;
219 lon = getbesl(buf, 19) / 3600000.0;
220 alt = getbesl(buf, 23) / 100.0;
221 speed = (float)(getbeuw(buf, 31) / 100.0);
222 track = (float)(getbeuw(buf, 33) / 10.0);
223 dop = (float)(getbeuw(buf, 35) / 10.0);
224 dopt = (unsigned char)getub(buf, 37);
225 nvis = (unsigned char)getub(buf, 38);
226 nsat = (unsigned char)getub(buf, 39);
227 status = (unsigned char)getub(buf, 72);
229 (void)mvwprintw(Ea1win, 1, 7, "%04d-%02d-%02d %02d:%02d:%02d.%09d",
230 year, mon, day, hour, min, sec, nsec);
231 (void)mvwprintw(Ea1win, 1, 47, "%10.6lf %c",
232 fabs(lat), lat < 0 ? 'S' : lat > 0 ? 'N' : ' ');
233 (void)mvwprintw(Ea1win, 1, 66, "%10.6lf %c",
234 fabs(lon), lat < 0 ? 'W' : lon > 0 ? 'E' : ' ');
236 (void)mvwprintw(Ea1win, 2, 50, "%6.2f m/s", speed);
237 (void)mvwprintw(Ea1win, 2, 70, "%5.1f", track);
238 (void)mvwprintw(Ea1win, 3, 68, "%8.2f m", alt);
240 /*@ -predboolothers @*/
241 (void)snprintf(statusbuf, sizeof(statusbuf), "%s%s%s%s%s%s%s%s",
242 status & 0x80 ? "PProp " : "",
243 status & 0x40 ? "PoorGeom " : "",
244 status & 0x20 ? "3D " : "",
245 status & 0x10 ? "2D " : "",
246 status & 0x08 ? "Acq/PHold " : "",
247 status & 0x04 ? "Diff " : "",
248 status & 0x02 ? "Ins (<3 SV) " : "",
249 status & 0x01 ? "BadAlm " : "");
250 /*@ +predboolothers @*/
252 (void)mvwprintw(Ea1win, 3, 24, "%-37s", statusbuf);
254 (void)mvwprintw(Ea1win, 2, 10, "%-10s", antenna[dopt >> 6]);
256 /*@ -predboolothers @*/
257 (void)mvwprintw(Ea1win, 2, 27, "%s %4.1f",
258 dopt & 1 ? "hdop" : "pdop", dop);
259 /*@ +predboolothers @*/
261 (void)mvwprintw(Ea1win, 3, 10, "%d/%d ", nsat, nvis);
264 for (i = 0; i < 8; i++) {
265 unsigned char sv, mode, sn, status;
268 sv = (unsigned char)getub(buf, off);
269 mode = (unsigned char)getub(buf, off + 1);
270 sn = (unsigned char)getub(buf, off + 2);
271 status = (unsigned char)getub(buf, off + 3);
272 (void)wmove(Eawin, (int)(i + 2), 3);
273 (void)wprintw(Eawin, " %3d", sv);
275 if (mode <= (unsigned char)8)
276 (void)wprintw(Eawin, " %4s", sv_mode[mode]);
278 (void)wprintw(Eawin, " -");
279 (void)wprintw(Eawin, " %3d", sn);
280 /*@ -predboolothers @*/
281 (void)wprintw(Eawin, " %c%c%c%c%c%c%c%c", (status & 0x80) ? 'p' : ' ', /* used for pos fix */
282 (status & 0x40) ? 'M' : ' ', /* momentum alert */
283 (status & 0x20) ? 's' : ' ', /* anti-spoof */
284 (status & 0x10) ? 'U' : ' ', /* unhealthy */
285 (status & 0x08) ? 'I' : ' ', /* inaccurate */
286 (status & 0x04) ? 'S' : ' ', /* spare */
287 (status & 0x02) ? 't' : ' ', /* used for time sol */
288 (status & 0x01) ? 'P' : ' '); /* parity error */
289 /*@ +predboolothers @*/
295 case ONCTYPE('B', 'b'):
297 unsigned int Bblines[12];
298 unsigned int Bblines_mask;
299 unsigned int next_line;
303 ch = (unsigned int)getub(buf, 4);
306 /* Try to align the entries for each SV of the Bb message at
307 * the same lines as in the Ea message.
309 memset(Bblines, 0, sizeof(Bblines));
311 for (i = 0; i < ch; i++) {
313 sv = (unsigned char)getub(buf, off);
315 for (j = 0; j < 8; j++)
316 if (EaSVlines[j] == sv && !(Bblines_mask & (1 << (j + 2)))) {
318 Bblines_mask |= 1 << Bblines[i];
322 /* SVs not seen in Ea fill lines left over. */
324 for (i = 0; i < ch; i++) {
325 if (Bblines[i] == 0) {
326 while (Bblines_mask & (1 << next_line))
328 Bblines[i] = next_line++;
329 Bblines_mask |= 1 << Bblines[i];
332 /* Ready to print on precalculated lines. */
333 for (i = 0; i < ch; i++) {
334 int doppl, el, az, health;
337 sv = (unsigned char)getub(buf, off);
338 doppl = (int)getbesw(buf, off + 1);
339 el = (int)getub(buf, off + 3);
340 az = (int)getbeuw(buf, off + 4);
341 health = (int)getub(buf, off + 5);
343 (void)wmove(Bbwin, (int)Bblines[i], 1);
344 (void)wprintw(Bbwin, "%3d %3d %2d %5d %c%c", sv, az, el, doppl, (health & 0x02) ? 'U' : ' ', /* unhealthy */
345 (health & 0x01) ? 'R' : ' '); /* removed */
348 for (i = 2; i < 14; i++)
350 if (!(Bblines_mask & (1 << i))) {
351 (void)wmove(Bbwin, (int)i, 1);
352 (void)wprintw(Bbwin, " ");
360 case ONCTYPE('E', 'n'):
362 unsigned char traim, ctrl, pulse, sync, sol_stat, status;
365 traim = (unsigned char)getub(buf, 5);
366 alarm = (float)(getbeuw(buf, 6) / 10.);
367 ctrl = (unsigned char)getub(buf, 8);
368 pulse = (unsigned char)getub(buf, 9);
369 sync = (unsigned char)getub(buf, 10);
370 sol_stat = (unsigned char)getub(buf, 11);
371 status = (unsigned char)getub(buf, 12);
372 sigma = (float)(getbeuw(buf, 13));
374 /*@ -predboolothers @*/
375 (void)mvwprintw(Enwin, 1, 24, "%3s", traim ? "on" : "off");
376 (void)mvwprintw(Enwin, 2, 18, "%6.1f us", alarm);
377 (void)mvwprintw(Enwin, 3, 13, "%14s", pps_ctrl[ctrl]);
378 (void)mvwprintw(Enwin, 4, 24, "%3s", pulse ? "on" : "off");
379 (void)mvwprintw(Enwin, 5, 24, "%3s", pps_sync[sync]);
380 (void)mvwprintw(Enwin, 6, 20, "%7s", traim_sol[sol_stat]);
381 (void)mvwprintw(Enwin, 7, 11, "%16s", traim_status[status]);
382 (void)mvwprintw(Enwin, 8, 18, "%6.3f us", sigma);
383 /*@ +predboolothers @*/
389 case ONCTYPE('B', 'o'):
391 unsigned char utc_offset;
393 utc_offset = (unsigned char)getub(buf, 4);
395 if (utc_offset != (unsigned char)0)
396 (void)mvwprintw(Bowin, 2, 2, "GPS%+4d", utc_offset);
398 (void)mvwprintw(Bowin, 2, 2, "unknown", utc_offset);
404 case ONCTYPE('A', 'y'):
408 pps_delay = getbesl(buf, 4) / 1000000.0;
410 (void)mvwprintw(Aywin, 2, 2, " %7.3f ms", pps_delay);
416 case ONCTYPE('A', 't'):
420 mode = (unsigned char)getub(buf, 4);
422 (void)mvwprintw(Atwin, 2, 1, "%6s", pos_hold_mode[mode]);
428 case ONCTYPE('A', 's'):
430 double lat, lon, alt;
432 lat = getbesl(buf, 4) / 3600000.0;
433 lon = getbesl(buf, 8) / 3600000.0;
434 alt = getbesl(buf, 12) / 100.0;
436 (void)mvwprintw(Aswin, 1, 5, "%10.6lf %c",
437 fabs(lat), lat < 0 ? 'S' : lat > 0 ? 'N' : ' ');
438 (void)mvwprintw(Aswin, 2, 5, "%10.6lf %c",
439 fabs(lon), lat < 0 ? 'W' : lon > 0 ? 'E' : ' ');
440 (void)mvwprintw(Aswin, 3, 7, "%8.2f m", alt);
447 monitor_log("%c%c =", buf[2], buf[3]);
452 static int oncore_command(char line[]UNUSED)
454 return COMMAND_UNKNOWN;
457 static void oncore_wrap(void)
459 (void)delwin(Ea1win);
469 const struct monitor_object_t oncore_mmt = {
470 .initialize = oncore_initialize,
471 .update = oncore_update,
472 .command = oncore_command,
474 .min_y = 20,.min_x = 80, /* size of the device window */
475 .driver = &oncore_binary,
478 #endif /* defined(ONCORE_ENABLE) && defined(BINARY_ENABLE) */