/* $Id$ */ /* * SiRF object for the GPS packet monitor. * */ #include #include #include #include #include #ifndef S_SPLINT_S #include #endif /* S_SPLINT_S */ #include #include #include #include "gpsd_config.h" #ifdef HAVE_NCURSES_H #include #else #include #endif /* HAVE_NCURSES_H */ #include "gpsd.h" #include "bits.h" #include "gpsmon.h" #if defined(SIRF_ENABLE) && defined(BINARY_ENABLE) extern const struct gps_type_t sirf_binary; static WINDOW *mid2win, *mid4win, *mid6win, *mid7win, *mid9win, *mid13win; static WINDOW *mid19win, *mid27win; static bool dispmode = false, subframe_enabled = false;; static int nfix,fix[20]; /*@ -nullassign @*/ static char *verbpat[] = { "#Time:", "@R Time:", "CSTD: New almanac for", "NOTICE: DOP Q Boost", "RTC not set", "numOfSVs = 0", "rtcaj tow ", NULL }; /*@ +nullassign @*/ static char *dgpsvec[] = { "None", "SBAS", "Serial", "Beacon", "Software", }; /***************************************************************************** * * SiRF packet-decoding routines * *****************************************************************************/ #define display (void)mvwprintw #define MAXSATS 12 /* the most satellites we can dump data on */ static bool sirf_initialize(void) { unsigned int i; /*@ -onlytrans @*/ mid2win = subwin(devicewin, 7, 80, 1, 0); mid4win = subwin(devicewin, MAXSATS+3, 30, 8, 0); mid6win = subwin(devicewin, 3, 50, 8, 30); mid7win = subwin(devicewin, 4, 50, 11, 30); mid9win = subwin(devicewin, 3, 50, 15, 30); mid13win = subwin(devicewin, 3, 50, 18, 30); mid19win = newwin(16, 50, 8, 30); mid27win = subwin(devicewin, 3, 50, 21, 30); if (mid2win==NULL || mid4win==NULL || mid6win==NULL || mid9win==NULL || mid13win==NULL || mid19win==NULL || mid27win==NULL) return false; (void)syncok(mid2win, true); (void)syncok(mid4win, true); (void)syncok(mid6win, true); (void)syncok(mid7win, true); (void)syncok(mid9win, true); (void)syncok(mid13win, true); (void)syncok(mid27win, true); /*@ -nullpass @*/ (void)wborder(mid2win, 0, 0, 0, 0, 0, 0, 0, 0), (void)wattrset(mid2win, A_BOLD); (void)wmove(mid2win, 0,1); display(mid2win, 0, 12, " X "); display(mid2win, 0, 21, " Y "); display(mid2win, 0, 30, " Z "); display(mid2win, 0, 43, " North "); display(mid2win, 0, 54, " East "); display(mid2win, 0, 65, " Alt "); (void)wmove(mid2win, 1,1); (void)wprintw(mid2win, "Pos: m m"); (void)wmove(mid2win, 2,1); (void)wprintw(mid2win, "Vel: m/s climb m/s"); (void)wmove(mid2win, 3,1); (void)wprintw(mid2win, "Week+TOW: Day: Heading: speed m/s"); (void)wmove(mid2win, 4,1); (void)wprintw(mid2win, "Skew: TZ: HDOP: M1: M2: "); (void)wmove(mid2win, 5,1); (void)wprintw(mid2win, "Fix:"); display(mid2win, 6, 24, " Packet type 2 (0x02) "); (void)wattrset(mid2win, A_NORMAL); (void)wborder(mid4win, 0, 0, 0, 0, 0, 0, 0, 0), (void)wattrset(mid4win, A_BOLD); display(mid4win, 1, 1, "Ch PRN Az El Stat C/N ? A"); for (i = 0; i < MAXSATS; i++) { display(mid4win, (int)(i+2), 1, "%2d",i); } display(mid4win, 14, 4, " Packet Type 4 (0x04) "); (void)wattrset(mid4win, A_NORMAL); (void)wborder(mid19win, 0, 0, 0, 0, 0, 0, 0, 0), (void)wattrset(mid19win, A_BOLD); display(mid19win, 1, 1, "Alt. hold mode:"); display(mid19win, 2, 1, "Alt. hold source:"); display(mid19win, 3, 1, "Alt. source input:"); display(mid19win, 4, 1, "Degraded timeout:"); display(mid19win, 5, 1, "DR timeout:"); display(mid19win, 6, 1, "Track smooth mode:"); display(mid19win, 7, 1, "Static Navigation:"); display(mid19win, 8, 1, "3SV Least Squares:"); display(mid19win, 9 ,1, "DOP Mask mode:"); display(mid19win, 10,1, "Nav. Elev. mask:"); display(mid19win, 11,1, "Nav. Power mask:"); display(mid19win, 12,1, "DGPS Source:"); display(mid19win, 13,1, "DGPS Mode:"); display(mid19win, 14,1, "DGPS Timeout:"); display(mid19win, 1, 26,"LP Push-to-Fix:"); display(mid19win, 2, 26,"LP On Time:"); display(mid19win, 3, 26,"LP Interval:"); display(mid19win, 4, 26,"U. Tasks Enab.:"); display(mid19win, 5, 26,"U. Task Inter.:"); display(mid19win, 6, 26,"LP Pwr Cyc En:"); display(mid19win, 7, 26,"LP Max Acq Srch:"); display(mid19win, 8, 26,"LP Max Off Time:"); display(mid19win, 9, 26,"APM enabled:"); display(mid19win,10, 26,"# of Fixes:"); display(mid19win,11, 26,"Time btw Fixes:"); display(mid19win,12, 26,"H/V Error Max:"); display(mid19win,13, 26,"Rsp Time Max:"); display(mid19win,14, 26,"Time/Accu:"); display(mid19win, 15, 8, " Packet type 19 (0x13) "); (void)wattrset(mid19win, A_NORMAL); (void)wborder(mid6win, 0, 0, 0, 0, 0, 0, 0, 0), (void)wattrset(mid6win, A_BOLD); display(mid6win, 1, 1, "Version:"); display(mid6win, 2, 8, " Packet Type 6 (0x06) "); (void)wattrset(mid6win, A_NORMAL); (void)wborder(mid7win, 0, 0, 0, 0, 0, 0, 0, 0), (void)wattrset(mid7win, A_BOLD); display(mid7win, 1, 1, "SVs: "); display(mid7win, 1, 9, "Drift: "); display(mid7win, 1, 23, "Bias: "); display(mid7win, 2, 1, "Estimated GPS Time: "); display(mid7win, 3, 8, " Packet type 7 (0x07) "); (void)wattrset(mid7win, A_NORMAL); (void)wborder(mid9win, 0, 0, 0, 0, 0, 0, 0, 0), (void)wattrset(mid9win, A_BOLD); display(mid9win, 1, 1, "Max: "); display(mid9win, 1, 13, "Lat: "); display(mid9win, 1, 25, "Time: "); display(mid9win, 1, 39, "MS: "); display(mid9win, 2, 8, " Packet type 9 (0x09) "); (void)wattrset(mid9win, A_NORMAL); (void)wborder(mid13win, 0, 0, 0, 0, 0, 0, 0, 0), (void)wattrset(mid13win, A_BOLD); display(mid13win, 1, 1, "SVs: "); display(mid13win, 1, 9, "="); display(mid13win, 2, 8, " Packet type 13 (0x0D) "); (void)wattrset(mid13win, A_NORMAL); (void)wborder(mid27win, 0, 0, 0, 0, 0, 0, 0, 0), (void)wattrset(mid27win, A_BOLD); display(mid27win, 1, 1, "DGPS source: "); display(mid27win, 1, 31, "Corrections: "); display(mid27win, 2, 8, " Packet type 27 (0x1B) "); (void)wattrset(mid27win, A_NORMAL); /*@ +nullpass @*/ /*@ -onlytrans @*/ #ifdef ALLOW_CONTROLSEND /* probe for version */ /*@ -compdef @*/ (void)monitor_control_send((unsigned char *)"\x84\x00", 2); /*@ +compdef @*/ #endif /* ALLOW_CONTROLSEND */ return true; } static void decode_time(int week, int tow) { int day = tow / 8640000; int tod = tow % 8640000; int h = tod / 360000; int m = tod % 360000; int s = m % 6000; m = (m - s) / 6000; (void)wmove(mid2win, 3,10); (void)wprintw(mid2win, "%4d+%9.2f", week, (double)tow/100); (void)wmove(mid2win, 3, 30); (void)wprintw(mid2win, "%d %02d:%02d:%05.2f", day, h,m,(double)s/100); (void)wmove(mid2win, 4, 8); (void)wattrset(mid2win, A_UNDERLINE); (void)wprintw(mid2win, "%f", timestamp()-gpstime_to_unix(week,tow/100.0)); (void)wmove(mid2win, 4, 29); (void)wprintw(mid2win, "%d", gmt_offset); (void)wattrset(mid2win, A_NORMAL); } static void decode_ecef(double x, double y, double z, double vx, double vy, double vz) { const double a = 6378137; const double f = 1 / 298.257223563; const double b = a * (1 - f); const double e2 = (a*a - b*b) / (a*a); const double e_2 = (a*a - b*b) / (b*b); double lambda,p,theta,phi,n,h,vnorth,veast,vup,speed,heading; lambda = atan2(y,x); /*@ -evalorder @*/ p = sqrt(pow(x,2) + pow(y,2)); theta = atan2(z*a,p*b); phi = atan2(z + e_2*b*pow(sin(theta),3),p - e2*a*pow(cos(theta),3)); n = a / sqrt(1.0 - e2*pow(sin(phi),2)); h = p / cos(phi) - n; h -= wgs84_separation((double)(RAD_2_DEG*phi),(double)(RAD_2_DEG*lambda)); vnorth = -vx*sin(phi)*cos(lambda)-vy*sin(phi)*sin(lambda)+vz*cos(phi); veast = -vx*sin(lambda)+vy*cos(lambda); vup = vx*cos(phi)*cos(lambda)+vy*cos(phi)*sin(lambda)+vz*sin(phi); speed = sqrt(pow(vnorth,2) + pow(veast,2)); heading = atan2(veast,vnorth); /*@ +evalorder @*/ if (heading < 0) heading += 2 * GPS_PI; (void)wattrset(mid2win, A_UNDERLINE); (void)wmove(mid2win, 1,40); (void)wprintw(mid2win, "%9.5f %9.5f",(double)(RAD_2_DEG*phi), (double)(RAD_2_DEG*lambda)); (void)mvwaddch(mid2win, 1, 49, ACS_DEGREE); (void)mvwaddch(mid2win, 1, 59, ACS_DEGREE); (void)wmove(mid2win, 1,61); (void)wprintw(mid2win, "%8d",(int)h); (void)wmove(mid2win, 2,40); (void)wprintw(mid2win, "%9.1f %9.1f",vnorth,veast); (void)wmove(mid2win, 2,61); (void)wprintw(mid2win, "%8.1f",vup); (void)wmove(mid2win, 3,54); (void)wprintw(mid2win, "%5.1f",(double)(RAD_2_DEG*heading)); (void)mvwaddch(mid2win, 3, 59, ACS_DEGREE); (void)wmove(mid2win, 3,61); (void)wprintw(mid2win, "%8.1f",speed); (void)wattrset(mid2win, A_NORMAL); } /*@ -globstate */ static void sirf_update(void) { int i,j,ch,off,cn; unsigned char *buf; size_t len; assert(mid27win != NULL); buf = session.packet.outbuffer + 4; len = session.packet.outbuflen - 8; switch (buf[0]) { case 0x02: /* Measured Navigation Data */ (void)wmove(mid2win, 1,6); /* ECEF position */ (void)wprintw(mid2win, "%8d %8d %8d",getbesl(buf, 1),getbesl(buf, 5),getbesl(buf, 9)); (void)wmove(mid2win, 2,6); /* ECEF velocity */ (void)wprintw(mid2win, "%8.1f %8.1f %8.1f", (double)getbesw(buf, 13)/8,(double)getbesw(buf, 15)/8,(double)getbesw(buf, 17)/8); decode_ecef((double)getbesl(buf, 1),(double)getbesl(buf, 5),(double)getbesl(buf, 9), (double)getbesw(buf, 13)/8,(double)getbesw(buf, 15)/8,(double)getbesw(buf, 17)/8); decode_time((int)getbeuw(buf, 22),getbesl(buf, 24)); /* line 4 */ (void)wmove(mid2win, 4,49); (void)wprintw(mid2win, "%4.1f",(double)getub(buf, 20)/5); /* HDOP */ (void)wmove(mid2win, 4,58); (void)wprintw(mid2win, "%02x",getub(buf, 19)); /* Mode 1 */ (void)wmove(mid2win, 4,70); (void)wprintw(mid2win, "%02x",getub(buf, 21)); /* Mode 2 */ (void)wmove(mid2win, 5,7); nfix = (int)getub(buf, 28); (void)wprintw(mid2win, "%d = ",nfix); /* SVs in fix */ for (i = 0; i < MAXSATS; i++) { /* SV list */ if (i < nfix) (void)wprintw(mid2win, "%3d",fix[i] = (int)getub(buf, 29+i)); else (void)wprintw(mid2win, " "); } monitor_log("MND 0x02="); break; case 0x04: /* Measured Tracking Data */ decode_time((int)getbeuw(buf, 1),getbesl(buf, 3)); ch = (int)getub(buf, 7); for (i = 0; i < ch; i++) { int sv,st; off = 8 + 15 * i; (void)wmove(mid4win, i+2, 3); sv = (int)getub(buf, off); (void)wprintw(mid4win, " %3d",sv); (void)wprintw(mid4win, " %3d%3d %04x",((int)getub(buf, off+1)*3)/2,(int)getub(buf, off+2)/2,(int)getbesw(buf, off+3)); st = ' '; if ((int)getbeuw(buf, off+3) == 0xbf) st = 'T'; for (j = 0; j < nfix; j++) if (sv == fix[j]) { st = 'N'; break; } cn = 0; for (j = 0; j < 10; j++) cn += (int)getub(buf, off+5+j); (void)wprintw(mid4win, "%5.1f %c",(double)cn/10,st); if (sv == 0) /* not tracking? */ (void)wprintw(mid4win, " "); /* clear other info */ } monitor_log("MTD 0x04="); break; #ifdef __UNUSED__ case 0x05: /* raw track data */ for (off = 1; off < len; off += 51) { ch = getbeul(buf, off); (void)wmove(mid4win, ch+2, 19); cn = 0; for (j = 0; j < 10; j++) cn += getub(buf, off+34+j); printw("%5.1f",(double)cn/10); printw("%9d%3d%5d",getbeul(buf, off+8),(int)getbeuw(buf, off+12),(int)getbeuw(buf, off+14)); printw("%8.5f %10.5f", (double)getbeul(buf, off+16)/65536,(double)getbeul(buf, off+20)/1024); } monitor_log("RTD 0x05="); break; #endif /* __UNUSED */ case 0x06: /* firmware version */ display(mid6win, 1, 10, "%s",buf + 1); monitor_log("FV 0x06="); break; case 0x07: /* Response - Clock Status Data */ decode_time((int)getbeuw(buf, 1),getbesl(buf, 3)); display(mid7win, 1, 5, "%2d", getub(buf, 7)); /* SVs */ display(mid7win, 1, 16, "%lu", getbeul(buf, 8)); /* Clock drift */ display(mid7win, 1, 29, "%lu", getbeul(buf, 12)); /* Clock Bias */ display(mid7win, 2, 21, "%lu", getbeul(buf, 16)); /* Estimated Time */ monitor_log("CSD 0x07="); break; case 0x08: /* 50 BPS data */ ch = (int)getub(buf, 1); display(mid4win, ch+2, 27, "Y"); monitor_log("50B 0x08="); subframe_enabled = true; break; case 0x09: /* Throughput */ display(mid9win, 1, 6, "%.3f",(double)getbeuw(buf, 1)/186); /*SegStatMax*/ display(mid9win, 1, 18, "%.3f",(double)getbeuw(buf, 3)/186); /*SegStatLat*/ display(mid9win, 1, 31, "%.3f",(double)getbeuw(buf, 5)/186); /*SegStatTime*/ display(mid9win, 1, 42, "%3d",(int)getbeuw(buf, 7)); /* Last Millisecond */ monitor_log("THR 0x09="); break; case 0x0b: /* Command Acknowledgement */ monitor_log("ACK 0x0b="); break; case 0x0c: /* Command NAcknowledgement */ monitor_log("NAK 0x0c="); break; case 0x0d: /* Visible List */ display(mid13win, 1, 6, "%02d",getub(buf, 1)); (void)wmove(mid13win, 1, 10); for (i = 0; i < MAXSATS; i++) { if (i < (int)getub(buf, 1)) (void)wprintw(mid13win, " %2d",getub(buf, 2 + 5 * i)); else (void)wprintw(mid13win, " "); } monitor_log("VL 0x0d="); break; case 0x13: #define YESNO(n) (((int)getub(buf, n) != 0)?'Y':'N') display(mid19win, 1, 20, "%d", getub(buf, 5)); /* Alt. hold mode */ display(mid19win, 2, 20, "%d", getub(buf, 6)); /* Alt. hold source*/ display(mid19win, 3, 20, "%dm", (int)getbeuw(buf, 7)); /* Alt. source input */ if (getub(buf, 9) != (unsigned char)'\0') display(mid19win, 4, 20, "%dsec", getub(buf, 10)); /* Degraded timeout*/ else display(mid19win, 4, 20, "N/A "); display(mid19win, 5, 20, "%dsec",getub(buf, 11)); /* DR timeout*/ display(mid19win, 6, 20, "%c", YESNO(12));/* Track smooth mode*/ display(mid19win, 7, 20, "%c", YESNO(13)); /* Static Nav.*/ display(mid19win, 8, 20, "0x%x", getub(buf, 14)); /* 3SV Least Squares*/ display(mid19win, 9 ,20, "0x%x", getub(buf, 19)); /* DOP Mask mode*/ display(mid19win, 10,20, "0x%x", (int)getbeuw(buf, 20)); /* Nav. Elev. mask*/ display(mid19win, 11,20, "0x%x", getub(buf, 22)); /* Nav. Power mask*/ display(mid19win, 12,20, "0x%x", getub(buf, 27)); /* DGPS Source*/ display(mid19win, 13,20, "0x%x", getub(buf, 28)); /* DGPS Mode*/ display(mid19win, 14,20, "%dsec",getub(buf, 29)); /* DGPS Timeout*/ display(mid19win, 1, 42, "%c", YESNO(34));/* LP Push-to-Fix */ display(mid19win, 2, 42, "%dms", getbeul(buf, 35)); /* LP On Time */ display(mid19win, 3, 42, "%d", getbeul(buf, 39)); /* LP Interval */ display(mid19win, 4, 42, "%c", YESNO(43));/* User Tasks enabled */ display(mid19win, 5, 42, "%d", getbeul(buf, 44)); /* User Task Interval */ display(mid19win, 6, 42, "%c", YESNO(48));/* LP Power Cycling Enabled */ display(mid19win, 7, 42, "%d", getbeul(buf, 49));/* LP Max Acq Search Time */ display(mid19win, 8, 42, "%d", getbeul(buf, 53));/* LP Max Off Time */ display(mid19win, 9, 42, "%c", YESNO(57));/* APM Enabled */ display(mid19win,10, 42, "%d", (int)getbeuw(buf, 58));/* # of fixes */ display(mid19win,11, 42, "%d", (int)getbeuw(buf, 60));/* Time Between fixes */ display(mid19win,12, 42, "%d", getub(buf, 62));/* H/V Error Max */ display(mid19win,13, 42, "%d", getub(buf, 63));/* Response Time Max */ display(mid19win,14, 42, "%d", getub(buf, 64));/* Time/Accu & Duty Cycle Priority */ #undef YESNO break; case 0x1b: /****************************************************************** Not actually documented in any published materials. Here is what Chris Kuethe got from the SiRF folks, (plus some corrections from the GpsPaSsion forums): Start of message ---------------- Message ID 1 byte 27 Correction Source 1 byte 0=None, 1=SBAS, 2=Serial, 3=Beacon, 4=Software total: 2 bytes Middle part of message varies if using beacon or other: ------------------------------------------------------- If Beacon: Receiver Freq Hz 4 bytes Bit rate BPS 1 byte Status bit map 1 byte 01=Signal Valid, 02=Auto frequency detect 04=Auto bit rate detect Signal Magnitude 4 bytes Note: in internal units Signal Strength dB 2 bytes derived from Signal Magnitude SNR dB 2 bytes total: 14 bytes If Not Beacon: Correction Age[12] 1 byte x 12 Age in seconds in same order as follows Reserved 2 bytes total: 14 bytes End of Message -------------- Repeated 12 times (pad with 0 if less than 12 SV corrections): SVID 1 byte Correction (cm) 2 bytes (signed short) total 3 x 12 = 36 bytes ******************************************************************/ display(mid27win, 1, 14, "%d (%s)", getub(buf, 1), dgpsvec[(int)getub(buf, 1)]); /*@ -type @*/ //(void) wmove(mid27win, 2, 0); for (i = j = 0; i < 12; i++) { if (getub(buf, 16+3*i) != '\0') { //(void)wprintw(mid27win, " %d=%d", getub(buf, 16+3*i), getbesw(buf, 16+3*i+1)); j++; } } /*@ +type @*/ display(mid27win, 1, 44, "%d", j); monitor_log("DST 0x1b="); break; case 0x1C: /* NL Measurement Data */ case 0x1D: /* DGPS Data */ case 0x1E: /* SV State Data */ case 0x1F: /* NL Initialized Data */ subframe_enabled = true; break; case 0x29: /* Geodetic Navigation Message */ monitor_log("GNM 0x29="); break; case 0x32: /* SBAS Parameters */ monitor_log("SBP 0x32="); break; case 0x34: /* PPS Time */ monitor_log("PPS 0x34="); break; #ifdef __UNUSED__ case 0x62: attrset(A_BOLD); move(2,40); printw("%9.5f %9.5f",(double)(RAD_2_DEG*1e8*getbesl(buf, 1)), (double)(RAD_2_DEG*1e8*getbesl(buf, 5))); move(2,63); printw("%8d",getbesl(buf, 9)/1000); move(3,63); printw("%8.1f",(double)getbesl(buf, 17)/1000); move(4,54); if (getbeul(buf, 13) > 50) { double heading = RAD_2_DEG*1e8*getbesl(buf, 21); if (heading < 0) heading += 360; printw("%5.1f",heading); } else printw(" 0.0"); move(4,63); printw("%8.1f",(double)getbesl(buf, 13)/1000); attrset(A_NORMAL); move(5,13); printw("%04d-%02d-%02d %02d:%02d:%02d.%02d", (int)getbeuw(buf, 26),getub(buf, 28),getub(buf, 29),getub(buf, 30),getub(buf, 31), (unsigned short)getbeuw(buf, 32)/1000, ((unsigned short)getbeuw(buf, 32)%1000)/10); { struct timeval clk,gps; struct tm tm; gettimeofday(&clk,NULL); memset(&tm,0,sizeof(tm)); tm.tm_sec = (unsigned short)getbeuw(buf, 32)/1000; tm.tm_min = (int)getub(buf, 31); tm.tm_hour = (int)getub(buf, 30); tm.tm_mday = (int)getub(buf, 29); tm.tm_mon = (int)getub(buf, 28) - 1; tm.tm_year = (int)getbeuw(buf, 26) - 1900; gps.tv_sec = mkgmtime(&tm); gps.tv_usec = (((unsigned short)getbeuw(buf, 32)%1000)/10) * 10000; move(5,2); printw(" "); move(5,2); #if 1 printw("%ld",(gps.tv_usec - clk.tv_usec) + ((gps.tv_sec - clk.tv_sec) % 3600) * 1000000); #else printw("%ld %ld %ld %ld",gps.tv_sec % 3600,gps.tv_usec, clk.tv_sec % 3600,clk.tv_usec); #endif } monitor_log("??? 0x62="); break; #endif /* __UNUSED__ */ case 0xff: /* Development Data */ /*@ +ignoresigns @*/ while (len > 0 && buf[len-1] == '\n') len--; while (len > 0 && buf[len-1] == ' ') len--; /*@ -ignoresigns @*/ buf[len] = '\0'; j = 1; for (i = 0; verbpat[i] != NULL; i++) if (strncmp((char *)(buf+1),verbpat[i],strlen(verbpat[i])) == 0) { j = 0; break; } if (j != 0) monitor_log("%s\n",buf+1); monitor_log("DD 0xff="); break; default: monitor_log(" 0x%02x=", buf[4]); break; } #ifdef ALLOW_CONTROLSEND /* elicit navigation parameters */ if (dispmode && (time(NULL) % 10 == 0)){ (void)monitor_control_send((unsigned char *)"\x98\x00", 2); } #endif /* ALLOW_CONTROLSEND */ /*@ -nullpass -nullderef @*/ if (dispmode) { (void)touchwin(mid19win); (void)wnoutrefresh(mid19win); } /*@ +nullpass -nullderef @*/ } /*@ +globstate */ #ifdef ALLOW_CONTROLSEND static int sirf_command(char line[]) { unsigned char buf[BUFSIZ]; int v; switch (line[0]) { case 'A': /* toggle 50bps subframe data */ (void)memset(buf, '\0', sizeof(buf)); putbyte(buf, 0, 0x80); putbyte(buf, 23, 12); putbyte(buf, 24, subframe_enabled ? 0x00 : 0x10); (void)monitor_control_send(buf, 25); return COMMAND_MATCH; case 'M': /* static navigation */ putbyte(buf, 0,0x8f); /* id */ putbyte(buf, 1, atoi(line+1)); (void)monitor_control_send(buf, 2); return COMMAND_MATCH; case 'D': /* MID 4 rate change (undocumented) */ v = atoi(line+1); if (v > 30) return COMMAND_MATCH; putbyte(buf, 0,0xa6); putbyte(buf, 1,0); putbyte(buf, 2, 4); /* satellite picture */ putbyte(buf, 3, v); putbyte(buf, 4, 0); putbyte(buf, 5, 0); putbyte(buf, 6, 0); putbyte(buf, 7, 0); (void)monitor_control_send(buf, 8); return COMMAND_MATCH; case 'P': /* poll navigation params */ dispmode = !dispmode; return COMMAND_MATCH; } return COMMAND_UNKNOWN; /* no match */ } #endif /* ALLOW_CONTROLSEND */ static void sirf_wrap(void) { (void)delwin(mid2win); (void)delwin(mid4win); (void)delwin(mid6win); (void)delwin(mid7win); (void)delwin(mid9win); (void)delwin(mid13win); (void)delwin(mid19win); (void)delwin(mid27win); } const struct monitor_object_t sirf_mmt = { .initialize = sirf_initialize, .update = sirf_update, #ifdef ALLOW_CONTROLSEND .command = sirf_command, #else .command = NULL, #endif /* ALLOW_CONTROLSEND */ .wrap = sirf_wrap, .min_y = 23, .min_x = 80, .driver = &sirf_binary, }; #endif /* defined(SIRF_ENABLE) && defined(BINARY_ENABLE) */ /* sirfmon.c ends here */