2 * SiRF 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.
15 #endif /* S_SPLINT_S */
20 #include "gpsd_config.h"
26 #endif /* HAVE_NCURSES_H */
32 #if defined(SIRF_ENABLE) && defined(BINARY_ENABLE)
33 extern const struct gps_type_t sirf_binary;
35 static WINDOW *mid2win, *mid4win, *mid6win, *mid7win, *mid9win, *mid13win;
36 static WINDOW *mid19win, *mid27win;
37 static bool dispmode = false, subframe_enabled = false;
38 static int nfix, fix[20];
41 static char *verbpat[] = {
44 "CSTD: New almanac for",
45 "NOTICE: DOP Q Boost",
54 static char *dgpsvec[] = {
62 /* check range of an unsigned quantity */
63 #define CHECK_RANGE(vec, i) ((i) < sizeof(vec)/sizeof(vec[0]))
65 /*****************************************************************************
67 * SiRF packet-decoding routines
69 *****************************************************************************/
71 #define display (void)mvwprintw
73 #define MAXSATS 12 /* the most satellites we can dump data on */
75 static bool sirf_initialize(void)
80 mid2win = subwin(devicewin, 7, 80, 1, 0);
81 mid4win = subwin(devicewin, MAXSATS + 3, 30, 8, 0);
82 mid6win = subwin(devicewin, 3, 50, 8, 30);
83 mid7win = subwin(devicewin, 4, 50, 11, 30);
84 mid9win = subwin(devicewin, 3, 50, 15, 30);
85 mid13win = subwin(devicewin, 3, 50, 18, 30);
86 mid19win = newwin(16, 50, 8, 30);
87 mid27win = subwin(devicewin, 3, 50, 21, 30);
88 if (mid2win == NULL || mid4win == NULL || mid6win == NULL
89 || mid9win == NULL || mid13win == NULL || mid19win == NULL
93 (void)syncok(mid2win, true);
94 (void)syncok(mid4win, true);
95 (void)syncok(mid6win, true);
96 (void)syncok(mid7win, true);
97 (void)syncok(mid9win, true);
98 (void)syncok(mid13win, true);
99 (void)syncok(mid27win, true);
102 (void)wborder(mid2win, 0, 0, 0, 0, 0, 0, 0, 0),
103 (void)wattrset(mid2win, A_BOLD);
104 (void)wmove(mid2win, 0, 1);
105 display(mid2win, 0, 12, " X ");
106 display(mid2win, 0, 21, " Y ");
107 display(mid2win, 0, 30, " Z ");
108 display(mid2win, 0, 43, " North ");
109 display(mid2win, 0, 54, " East ");
110 display(mid2win, 0, 65, " Alt ");
112 (void)wmove(mid2win, 1, 1);
113 (void)wprintw(mid2win,
115 (void)wmove(mid2win, 2, 1);
116 (void)wprintw(mid2win,
117 "Vel: m/s climb m/s");
118 (void)wmove(mid2win, 3, 1);
119 (void)wprintw(mid2win,
120 "Week+TOW: Day: Heading: speed m/s");
121 (void)wmove(mid2win, 4, 1);
122 (void)wprintw(mid2win,
123 "Skew: TZ: HDOP: M1: M2: ");
124 (void)wmove(mid2win, 5, 1);
125 (void)wprintw(mid2win, "Fix:");
126 display(mid2win, 6, 24, " Packet type 2 (0x02) ");
127 (void)wattrset(mid2win, A_NORMAL);
129 (void)wborder(mid4win, 0, 0, 0, 0, 0, 0, 0, 0),
130 (void)wattrset(mid4win, A_BOLD);
131 display(mid4win, 1, 1, "Ch PRN Az El Stat C/N ? A");
132 for (i = 0; i < MAXSATS; i++) {
133 display(mid4win, (int)(i + 2), 1, "%2d", i);
135 display(mid4win, 14, 4, " Packet Type 4 (0x04) ");
136 (void)wattrset(mid4win, A_NORMAL);
138 (void)wborder(mid19win, 0, 0, 0, 0, 0, 0, 0, 0),
139 (void)wattrset(mid19win, A_BOLD);
140 display(mid19win, 1, 1, "Alt. hold mode:");
141 display(mid19win, 2, 1, "Alt. hold source:");
142 display(mid19win, 3, 1, "Alt. source input:");
143 display(mid19win, 4, 1, "Degraded timeout:");
144 display(mid19win, 5, 1, "DR timeout:");
145 display(mid19win, 6, 1, "Track smooth mode:");
146 display(mid19win, 7, 1, "Static Navigation:");
147 display(mid19win, 8, 1, "3SV Least Squares:");
148 display(mid19win, 9, 1, "DOP Mask mode:");
149 display(mid19win, 10, 1, "Nav. Elev. mask:");
150 display(mid19win, 11, 1, "Nav. Power mask:");
151 display(mid19win, 12, 1, "DGPS Source:");
152 display(mid19win, 13, 1, "DGPS Mode:");
153 display(mid19win, 14, 1, "DGPS Timeout:");
154 display(mid19win, 1, 26, "LP Push-to-Fix:");
155 display(mid19win, 2, 26, "LP On Time:");
156 display(mid19win, 3, 26, "LP Interval:");
157 display(mid19win, 4, 26, "U. Tasks Enab.:");
158 display(mid19win, 5, 26, "U. Task Inter.:");
159 display(mid19win, 6, 26, "LP Pwr Cyc En:");
160 display(mid19win, 7, 26, "LP Max Acq Srch:");
161 display(mid19win, 8, 26, "LP Max Off Time:");
162 display(mid19win, 9, 26, "APM enabled:");
163 display(mid19win, 10, 26, "# of Fixes:");
164 display(mid19win, 11, 26, "Time btw Fixes:");
165 display(mid19win, 12, 26, "H/V Error Max:");
166 display(mid19win, 13, 26, "Rsp Time Max:");
167 display(mid19win, 14, 26, "Time/Accu:");
169 display(mid19win, 15, 8, " Packet type 19 (0x13) ");
170 (void)wattrset(mid19win, A_NORMAL);
172 (void)wborder(mid6win, 0, 0, 0, 0, 0, 0, 0, 0),
173 (void)wattrset(mid6win, A_BOLD);
174 display(mid6win, 1, 1, "Version:");
175 display(mid6win, 2, 8, " Packet Type 6 (0x06) ");
176 (void)wattrset(mid6win, A_NORMAL);
178 (void)wborder(mid7win, 0, 0, 0, 0, 0, 0, 0, 0),
179 (void)wattrset(mid7win, A_BOLD);
180 display(mid7win, 1, 1, "SVs: ");
181 display(mid7win, 1, 9, "Drift: ");
182 display(mid7win, 1, 23, "Bias: ");
183 display(mid7win, 2, 1, "Estimated GPS Time: ");
184 display(mid7win, 3, 8, " Packet type 7 (0x07) ");
185 (void)wattrset(mid7win, A_NORMAL);
187 (void)wborder(mid9win, 0, 0, 0, 0, 0, 0, 0, 0),
188 (void)wattrset(mid9win, A_BOLD);
189 display(mid9win, 1, 1, "Max: ");
190 display(mid9win, 1, 13, "Lat: ");
191 display(mid9win, 1, 25, "Time: ");
192 display(mid9win, 1, 39, "MS: ");
193 display(mid9win, 2, 8, " Packet type 9 (0x09) ");
194 (void)wattrset(mid9win, A_NORMAL);
196 (void)wborder(mid13win, 0, 0, 0, 0, 0, 0, 0, 0),
197 (void)wattrset(mid13win, A_BOLD);
198 display(mid13win, 1, 1, "SVs: ");
199 display(mid13win, 1, 9, "=");
200 display(mid13win, 2, 8, " Packet type 13 (0x0D) ");
201 (void)wattrset(mid13win, A_NORMAL);
203 (void)wborder(mid27win, 0, 0, 0, 0, 0, 0, 0, 0),
204 (void)wattrset(mid27win, A_BOLD);
205 display(mid27win, 1, 1, "DGPS source: ");
206 display(mid27win, 1, 31, "Corrections: ");
207 display(mid27win, 2, 8, " Packet type 27 (0x1B) ");
208 (void)wattrset(mid27win, A_NORMAL);
212 #ifdef ALLOW_CONTROLSEND
213 /* probe for version */
215 (void)monitor_control_send((unsigned char *)"\x84\x00", 2);
217 #endif /* ALLOW_CONTROLSEND */
222 static void decode_time(int week, int tow)
224 int day = tow / 8640000;
225 int tod = tow % 8640000;
226 int h = tod / 360000;
227 int m = tod % 360000;
232 (void)wmove(mid2win, 3, 10);
233 (void)wprintw(mid2win, "%4d+%9.2f", week, (double)tow / 100);
234 (void)wmove(mid2win, 3, 30);
235 (void)wprintw(mid2win, "%d %02d:%02d:%05.2f", day, h, m, (double)s / 100);
236 (void)wmove(mid2win, 4, 8);
237 (void)wattrset(mid2win, A_UNDERLINE);
238 (void)wprintw(mid2win, "%f",
239 timestamp() - gpstime_to_unix(week, tow / 100.0));
240 (void)wmove(mid2win, 4, 29);
241 (void)wprintw(mid2win, "%d", gmt_offset);
242 (void)wattrset(mid2win, A_NORMAL);
245 static void decode_ecef(double x, double y, double z,
246 double vx, double vy, double vz)
248 const double a = WGS84A;
249 const double b = WGS84B;
250 const double e2 = (a * a - b * b) / (a * a);
251 const double e_2 = (a * a - b * b) / (b * b);
252 double lambda, p, theta, phi, n, h, vnorth, veast, vup, speed, heading;
254 lambda = atan2(y, x);
256 p = sqrt(pow(x, 2) + pow(y, 2));
257 theta = atan2(z * a, p * b);
259 atan2(z + e_2 * b * pow(sin(theta), 3),
260 p - e2 * a * pow(cos(theta), 3));
261 n = a / sqrt(1.0 - e2 * pow(sin(phi), 2));
262 h = p / cos(phi) - n;
263 h -= wgs84_separation((double)(RAD_2_DEG * phi),
264 (double)(RAD_2_DEG * lambda));
266 -vx * sin(phi) * cos(lambda) - vy * sin(phi) * sin(lambda) +
268 veast = -vx * sin(lambda) + vy * cos(lambda);
270 vx * cos(phi) * cos(lambda) + vy * cos(phi) * sin(lambda) +
272 speed = sqrt(pow(vnorth, 2) + pow(veast, 2));
273 heading = atan2(veast, vnorth);
276 heading += 2 * GPS_PI;
278 (void)wattrset(mid2win, A_UNDERLINE);
279 (void)wmove(mid2win, 1, 40);
280 (void)wprintw(mid2win, "%9.5f %9.5f", (double)(RAD_2_DEG * phi),
281 (double)(RAD_2_DEG * lambda));
282 (void)mvwaddch(mid2win, 1, 49, ACS_DEGREE);
283 (void)mvwaddch(mid2win, 1, 59, ACS_DEGREE);
284 (void)wmove(mid2win, 1, 61);
285 (void)wprintw(mid2win, "%8d", (int)h);
287 (void)wmove(mid2win, 2, 40);
288 (void)wprintw(mid2win, "%9.1f %9.1f", vnorth, veast);
289 (void)wmove(mid2win, 2, 61);
290 (void)wprintw(mid2win, "%8.1f", vup);
292 (void)wmove(mid2win, 3, 54);
293 (void)wprintw(mid2win, "%5.1f", (double)(RAD_2_DEG * heading));
294 (void)mvwaddch(mid2win, 3, 59, ACS_DEGREE);
295 (void)wmove(mid2win, 3, 61);
296 (void)wprintw(mid2win, "%8.1f", speed);
297 (void)wattrset(mid2win, A_NORMAL);
301 static void sirf_update(void)
303 int i, j, ch, off, cn;
308 assert(mid27win != NULL);
309 buf = session.packet.outbuffer + 4;
310 len = session.packet.outbuflen - 8;
312 case 0x02: /* Measured Navigation Data */
313 (void)wmove(mid2win, 1, 6); /* ECEF position */
314 (void)wprintw(mid2win, "%8d %8d %8d", getbesl(buf, 1),
315 getbesl(buf, 5), getbesl(buf, 9));
316 (void)wmove(mid2win, 2, 6); /* ECEF velocity */
317 (void)wprintw(mid2win, "%8.1f %8.1f %8.1f",
318 (double)getbesw(buf, 13) / 8, (double)getbesw(buf,
320 (double)getbesw(buf, 17) / 8);
321 decode_ecef((double)getbesl(buf, 1), (double)getbesl(buf, 5),
322 (double)getbesl(buf, 9), (double)getbesw(buf, 13) / 8,
323 (double)getbesw(buf, 15) / 8, (double)getbesw(buf,
325 decode_time((int)getbeuw(buf, 22), getbesl(buf, 24));
327 (void)wmove(mid2win, 4, 49);
328 (void)wprintw(mid2win, "%4.1f", (double)getub(buf, 20) / 5); /* HDOP */
329 (void)wmove(mid2win, 4, 58);
330 (void)wprintw(mid2win, "%02x", getub(buf, 19)); /* Mode 1 */
331 (void)wmove(mid2win, 4, 70);
332 (void)wprintw(mid2win, "%02x", getub(buf, 21)); /* Mode 2 */
333 (void)wmove(mid2win, 5, 7);
334 nfix = (int)getub(buf, 28);
335 (void)wprintw(mid2win, "%d = ", nfix); /* SVs in fix */
336 for (i = 0; i < MAXSATS; i++) { /* SV list */
338 (void)wprintw(mid2win, "%3d", fix[i] =
339 (int)getub(buf, 29 + i));
341 (void)wprintw(mid2win, " ");
343 monitor_log("MND 0x02=");
346 case 0x04: /* Measured Tracking Data */
347 decode_time((int)getbeuw(buf, 1), getbesl(buf, 3));
348 ch = (int)getub(buf, 7);
349 for (i = 0; i < ch; i++) {
353 (void)wmove(mid4win, i + 2, 3);
354 sv = (int)getub(buf, off);
355 (void)wprintw(mid4win, " %3d", sv);
357 (void)wprintw(mid4win, " %3d%3d %04x",
358 ((int)getub(buf, off + 1) * 3) / 2, (int)getub(buf,
361 2, (int)getbesw(buf, off + 3));
364 if ((int)getbeuw(buf, off + 3) == 0xbf)
366 for (j = 0; j < nfix; j++)
374 for (j = 0; j < 10; j++)
375 cn += (int)getub(buf, off + 5 + j);
377 (void)wprintw(mid4win, "%5.1f %c", (double)cn / 10, st);
379 if (sv == 0) /* not tracking? */
380 (void)wprintw(mid4win, " "); /* clear other info */
382 monitor_log("MTD 0x04=");
386 case 0x05: /* raw track data */
387 for (off = 1; off < len; off += 51) {
388 ch = getbeul(buf, off);
389 (void)wmove(mid4win, ch + 2, 19);
392 for (j = 0; j < 10; j++)
393 cn += getub(buf, off + 34 + j);
395 printw("%5.1f", (double)cn / 10);
397 printw("%9d%3d%5d", getbeul(buf, off + 8),
398 (int)getbeuw(buf, off + 12), (int)getbeuw(buf, off + 14));
399 printw("%8.5f %10.5f", (double)getbeul(buf, off + 16) / 65536,
400 (double)getbeul(buf, off + 20) / 1024);
402 monitor_log("RTD 0x05=");
404 #endif /* __UNUSED */
406 case 0x06: /* firmware version */
407 display(mid6win, 1, 10, "%s", buf + 1);
408 monitor_log("FV 0x06=");
411 case 0x07: /* Response - Clock Status Data */
412 decode_time((int)getbeuw(buf, 1), getbesl(buf, 3));
413 display(mid7win, 1, 5, "%2d", getub(buf, 7)); /* SVs */
414 display(mid7win, 1, 16, "%lu", getbeul(buf, 8)); /* Clock drift */
415 display(mid7win, 1, 29, "%lu", getbeul(buf, 12)); /* Clock Bias */
416 display(mid7win, 2, 21, "%lu", getbeul(buf, 16)); /* Estimated Time */
417 monitor_log("CSD 0x07=");
420 case 0x08: /* 50 BPS data */
421 ch = (int)getub(buf, 1);
422 display(mid4win, ch + 2, 27, "Y");
423 monitor_log("50B 0x08=");
424 subframe_enabled = true;
427 case 0x09: /* Throughput */
428 display(mid9win, 1, 6, "%.3f", (double)getbeuw(buf, 1) / 186); /*SegStatMax */
429 display(mid9win, 1, 18, "%.3f", (double)getbeuw(buf, 3) / 186); /*SegStatLat */
430 display(mid9win, 1, 31, "%.3f", (double)getbeuw(buf, 5) / 186); /*SegStatTime */
431 display(mid9win, 1, 42, "%3d", (int)getbeuw(buf, 7)); /* Last Millisecond */
432 monitor_log("THR 0x09=");
435 case 0x0b: /* Command Acknowledgement */
436 monitor_log("ACK 0x0b=");
439 case 0x0c: /* Command NAcknowledgement */
440 monitor_log("NAK 0x0c=");
443 case 0x0d: /* Visible List */
444 display(mid13win, 1, 6, "%02d", getub(buf, 1));
445 (void)wmove(mid13win, 1, 10);
446 for (i = 0; i < MAXSATS; i++) {
447 if (i < (int)getub(buf, 1))
448 (void)wprintw(mid13win, " %2d", getub(buf, 2 + 5 * i));
450 (void)wprintw(mid13win, " ");
452 monitor_log("VL 0x0d=");
456 #define YESNO(n) (((int)getub(buf, n) != 0)?'Y':'N')
457 display(mid19win, 1, 20, "%d", getub(buf, 5)); /* Alt. hold mode */
458 display(mid19win, 2, 20, "%d", getub(buf, 6)); /* Alt. hold source */
459 display(mid19win, 3, 20, "%dm", (int)getbeuw(buf, 7)); /* Alt. source input */
460 if (getub(buf, 9) != (uint8_t) '\0')
461 display(mid19win, 4, 20, "%dsec", getub(buf, 10)); /* Degraded timeout */
463 display(mid19win, 4, 20, "N/A ");
464 display(mid19win, 5, 20, "%dsec", getub(buf, 11)); /* DR timeout */
465 display(mid19win, 6, 20, "%c", YESNO(12)); /* Track smooth mode */
466 display(mid19win, 7, 20, "%c", YESNO(13)); /* Static Nav. */
467 display(mid19win, 8, 20, "0x%x", getub(buf, 14)); /* 3SV Least Squares */
468 display(mid19win, 9, 20, "0x%x", getub(buf, 19)); /* DOP Mask mode */
469 display(mid19win, 10, 20, "0x%x", (int)getbeuw(buf, 20)); /* Nav. Elev. mask */
470 display(mid19win, 11, 20, "0x%x", getub(buf, 22)); /* Nav. Power mask */
471 display(mid19win, 12, 20, "0x%x", getub(buf, 27)); /* DGPS Source */
472 display(mid19win, 13, 20, "0x%x", getub(buf, 28)); /* DGPS Mode */
473 display(mid19win, 14, 20, "%dsec", getub(buf, 29)); /* DGPS Timeout */
474 display(mid19win, 1, 42, "%c", YESNO(34)); /* LP Push-to-Fix */
475 display(mid19win, 2, 42, "%dms", getbeul(buf, 35)); /* LP On Time */
476 display(mid19win, 3, 42, "%d", getbeul(buf, 39)); /* LP Interval */
477 display(mid19win, 4, 42, "%c", YESNO(43)); /* User Tasks enabled */
478 display(mid19win, 5, 42, "%d", getbeul(buf, 44)); /* User Task Interval */
479 display(mid19win, 6, 42, "%c", YESNO(48)); /* LP Power Cycling Enabled */
480 display(mid19win, 7, 42, "%d", getbeul(buf, 49)); /* LP Max Acq Search Time */
481 display(mid19win, 8, 42, "%d", getbeul(buf, 53)); /* LP Max Off Time */
482 display(mid19win, 9, 42, "%c", YESNO(57)); /* APM Enabled */
483 display(mid19win, 10, 42, "%d", (int)getbeuw(buf, 58)); /* # of fixes */
484 display(mid19win, 11, 42, "%d", (int)getbeuw(buf, 60)); /* Time Between fixes */
485 display(mid19win, 12, 42, "%d", getub(buf, 62)); /* H/V Error Max */
486 display(mid19win, 13, 42, "%d", getub(buf, 63)); /* Response Time Max */
487 display(mid19win, 14, 42, "%d", getub(buf, 64)); /* Time/Accu & Duty Cycle Priority */
492 /******************************************************************
493 Not actually documented in any published materials.
494 Here is what Chris Kuethe got from the SiRF folks,
495 (plus some corrections from the GpsPaSsion forums):
500 Correction Source 1 byte 0=None, 1=SBAS, 2=Serial, 3=Beacon,
505 Middle part of message varies if using beacon or other:
506 -------------------------------------------------------
508 Receiver Freq Hz 4 bytes
510 Status bit map 1 byte 01=Signal Valid,
511 02=Auto frequency detect
512 04=Auto bit rate detect
513 Signal Magnitude 4 bytes Note: in internal units
514 Signal Strength dB 2 bytes derived from Signal Magnitude
520 Correction Age[12] 1 byte x 12 Age in seconds in same order as follows
527 Repeated 12 times (pad with 0 if less than 12 SV corrections):
529 Correction (cm) 2 bytes (signed short)
531 total 3 x 12 = 36 bytes
532 ******************************************************************/
533 dgps = getub(buf, 1);
534 display(mid27win, 1, 14, "%d (%s)",
535 dgps, (CHECK_RANGE(dgpsvec, dgps) ? dgpsvec[dgps] : "???"));
537 //(void) wmove(mid27win, 2, 0);
538 for (i = j = 0; i < 12; i++) {
539 if (getub(buf, 16 + 3 * i) != '\0') {
540 //(void)wprintw(mid27win, " %d=%d", getub(buf, 16+3*i), getbesw(buf, 16+3*i+1));
545 display(mid27win, 1, 44, "%d", j);
546 monitor_log("DST 0x1b=");
549 case 0x1C: /* NL Measurement Data */
550 case 0x1D: /* DGPS Data */
551 case 0x1E: /* SV State Data */
552 case 0x1F: /* NL Initialized Data */
553 subframe_enabled = true;
555 case 0x29: /* Geodetic Navigation Message */
556 monitor_log("GNM 0x29=");
558 case 0x32: /* SBAS Parameters */
559 monitor_log("SBP 0x32=");
561 case 0x34: /* PPS Time */
562 monitor_log("PPS 0x34=");
569 printw("%9.5f %9.5f", (double)(RAD_2_DEG * 1e8 * getbesl(buf, 1)),
570 (double)(RAD_2_DEG * 1e8 * getbesl(buf, 5)));
572 printw("%8d", getbesl(buf, 9) / 1000);
576 printw("%8.1f", (double)getbesl(buf, 17) / 1000);
579 if (getbeul(buf, 13) > 50) {
580 double heading = RAD_2_DEG * 1e8 * getbesl(buf, 21);
583 printw("%5.1f", heading);
588 printw("%8.1f", (double)getbesl(buf, 13) / 1000);
592 printw("%04d-%02d-%02d %02d:%02d:%02d.%02d",
593 (int)getbeuw(buf, 26), getub(buf, 28), getub(buf, 29),
594 getub(buf, 30), getub(buf, 31), (unsigned short)getbeuw(buf,
596 1000, ((unsigned short)getbeuw(buf, 32) % 1000) / 10);
598 struct timeval clk, gps;
601 gettimeofday(&clk, NULL);
603 memset(&tm, 0, sizeof(tm));
604 tm.tm_sec = (unsigned short)getbeuw(buf, 32) / 1000;
605 tm.tm_min = (int)getub(buf, 31);
606 tm.tm_hour = (int)getub(buf, 30);
607 tm.tm_mday = (int)getub(buf, 29);
608 tm.tm_mon = (int)getub(buf, 28) - 1;
609 tm.tm_year = (int)getbeuw(buf, 26) - 1900;
611 gps.tv_sec = mkgmtime(&tm);
613 (((unsigned short)getbeuw(buf, 32) % 1000) / 10) * 10000;
619 printw("%ld", (gps.tv_usec - clk.tv_usec) +
620 ((gps.tv_sec - clk.tv_sec) % 3600) * 1000000);
622 printw("%ld %ld %ld %ld", gps.tv_sec % 3600, gps.tv_usec,
623 clk.tv_sec % 3600, clk.tv_usec);
626 monitor_log("??? 0x62=");
628 #endif /* __UNUSED__ */
630 case 0xff: /* Development Data */
632 while (len > 0 && buf[len - 1] == '\n')
634 while (len > 0 && buf[len - 1] == ' ')
639 for (i = 0; verbpat[i] != NULL; i++)
640 if (strncmp((char *)(buf + 1), verbpat[i], strlen(verbpat[i])) ==
646 monitor_log("%s\n", buf + 1);
647 monitor_log("DD 0xff=");
651 monitor_log(" 0x%02x=", buf[4]);
655 #ifdef ALLOW_CONTROLSEND
656 /* elicit navigation parameters */
657 if (dispmode && (time(NULL) % 10 == 0)) {
658 (void)monitor_control_send((unsigned char *)"\x98\x00", 2);
660 #endif /* ALLOW_CONTROLSEND */
662 /*@ -nullpass -nullderef @*/
664 (void)touchwin(mid19win);
665 (void)wnoutrefresh(mid19win);
667 /*@ +nullpass -nullderef @*/
672 #ifdef ALLOW_CONTROLSEND
673 static int sirf_command(char line[])
675 unsigned char buf[BUFSIZ];
679 case 'A': /* toggle 50bps subframe data */
680 (void)memset(buf, '\0', sizeof(buf));
681 putbyte(buf, 0, 0x80);
682 putbyte(buf, 23, 12);
683 putbyte(buf, 24, subframe_enabled ? 0x00 : 0x10);
684 (void)monitor_control_send(buf, 25);
685 return COMMAND_MATCH;
687 case 'M': /* static navigation */
688 putbyte(buf, 0, 0x8f); /* id */
689 putbyte(buf, 1, atoi(line + 1));
690 (void)monitor_control_send(buf, 2);
691 return COMMAND_MATCH;
693 case 'D': /* MID 4 rate change (undocumented) */
696 return COMMAND_MATCH;
697 putbyte(buf, 0, 0xa6);
699 putbyte(buf, 2, 4); /* satellite picture */
705 (void)monitor_control_send(buf, 8);
706 return COMMAND_MATCH;
708 case 'P': /* poll navigation params */
709 dispmode = !dispmode;
710 return COMMAND_MATCH;
713 return COMMAND_UNKNOWN; /* no match */
715 #endif /* ALLOW_CONTROLSEND */
717 static void sirf_wrap(void)
719 (void)delwin(mid2win);
720 (void)delwin(mid4win);
721 (void)delwin(mid6win);
722 (void)delwin(mid7win);
723 (void)delwin(mid9win);
724 (void)delwin(mid13win);
725 (void)delwin(mid19win);
726 (void)delwin(mid27win);
729 const struct monitor_object_t sirf_mmt = {
730 .initialize = sirf_initialize,
731 .update = sirf_update,
732 #ifdef ALLOW_CONTROLSEND
733 .command = sirf_command,
736 #endif /* ALLOW_CONTROLSEND */
738 .min_y = 23,.min_x = 80,
739 .driver = &sirf_binary,
741 #endif /* defined(SIRF_ENABLE) && defined(BINARY_ENABLE) */
743 /* sirfmon.c ends here */