Exemple #1
0
timestamp_t gpsd_utc_resolve(/*@in@*/struct gps_device_t *session)
/* resolve a UTC date, checking for rollovers */
{
    /*
     * We'd like to *correct* for rollover the way we do for GPS week.
     * In theory, comparing extracted UTC against present time should
     * allow us to compute the device's epoch assumption.  In practice,
     * this will be hairy and risky.
     */
    timestamp_t t;

    t = (timestamp_t)mkgmtime(&session->driver.nmea.date) +
	session->driver.nmea.subseconds;
    session->context->valid &=~ GPS_TIME_VALID;

    /*
     * If the system clock is zero or has a small-integer value,
     * no further sanity-checking is possible.
     */
    if (session->context->start_time < GPS_EPOCH)
	return t;

    /*
     * If the GPS is reporting a time from before the daemon started, we've
     * had a rollover event while the daemon was running.
     */
    if (session->newdata.time < (timestamp_t)session->context->start_time) {
	char scr[128];
	(void)unix_to_iso8601(session->newdata.time, scr, sizeof(scr));
	gpsd_report(LOG_WARN, "GPS week rollover makes time %s (%f) invalid\n",
		    scr, session->newdata.time);
    }

    return t;
}
Exemple #2
0
static void cooked_pvt(void)
{
    char scr[128];

    if (isnan(session.gpsdata.fix.time) == 0) {
	(void)unix_to_iso8601(session.gpsdata.fix.time, scr, sizeof(scr));
    } else
	(void)snprintf(scr, sizeof(scr), "n/a");
    (void)mvwprintw(cookedwin, 1, 7, "%-24s", scr);


    if (session.gpsdata.fix.mode >= MODE_2D
	&& isnan(session.gpsdata.fix.latitude) == 0) {
	(void)snprintf(scr, sizeof(scr), "%s %c",
		       deg_to_str(deg_ddmmss,
				  fabs(session.gpsdata.fix.latitude)),
		       (session.gpsdata.fix.latitude < 0) ? 'S' : 'N');
    } else
	(void)snprintf(scr, sizeof(scr), "n/a");
    (void)mvwprintw(cookedwin, 1, 37, "%-17s", scr);

    if (session.gpsdata.fix.mode >= MODE_2D
	&& isnan(session.gpsdata.fix.longitude) == 0) {
	(void)snprintf(scr, sizeof(scr), "%s %c",
		       deg_to_str(deg_ddmmss,
				  fabs(session.gpsdata.fix.longitude)),
		       (session.gpsdata.fix.longitude < 0) ? 'W' : 'E');
    } else
	(void)snprintf(scr, sizeof(scr), "n/a");
    (void)mvwprintw(cookedwin, 1, 60, "%-17s", scr);
}
Exemple #3
0
static void garmin_bin_update(uint16_t pkt_id, uint32_t pkt_size UNUSED, unsigned char *pkt_data)
{
    int i;
    cpo_sat_data *sats = NULL;
    cpo_pvt_data *pvt = NULL;
    //cpo_rcv_data *rmd = NULL;
    char tbuf[JSON_DATE_MAX+1];

    switch (pkt_id) {
    case 0x29:	/* Receiver Measurement Record */
    case 0x34:
	/* for future use */
	//rmd = (cpo_rcv_data *)pkt_data;
	monitor_log("RMD 0x%02x=", pkt_id);
	break;

    case 0x33:	/* Position Record */
	/* coverity_submit[tainted_data] */
	display(miscwin, 0, 6, "%-24s",
		unix_to_iso8601(session.gpsdata.fix.time, tbuf, sizeof(tbuf)));
	pvt = (cpo_pvt_data *)pkt_data;
	display(mid51win, 1, 7, "%s",
		(CHECK_RANGE(fixdesc, (uint8_t)GPSD_LE16TOH(pvt->fix)) ? \
			fixdesc[GPSD_LE16TOH(pvt->fix)] : "unknown"));
	display(mid51win, 2, 8, "%3.5f", pvt->lat * RAD_2_DEG);
	display(mid51win, 3, 8, "%3.5f", pvt->lon * RAD_2_DEG);
	display(mid51win, 4, 8, "%8.2f", pvt->alt + pvt->msl_hght);
	display(mid51win, 5, 9, "%5.1f", hypot(pvt->lon_vel, pvt->lat_vel));
	display(mid51win, 6, 9, "%5.1f", pvt->alt_vel);
	display(mid51win, 7, 8, "%d", (int)GPSD_LE16TOH(pvt->leap_sec));
	if (GPSD_LE16TOH(pvt->fix) < 2) /* error value is very large when status no fix */
	   pvt->epe = pvt->eph = pvt->epv = NAN;
	display(mid51win, 8, 7, "%6.2f", pvt->epe);
	display(mid51win, 9, 7, "%6.2f", pvt->eph);
	display(mid51win, 10, 7, "%6.2f", pvt->epv);
	monitor_log("PVT 0x%02x=", pkt_id);
	break;

    case 0x72:	/* Satellite Data Record */
	sats = (cpo_sat_data *)pkt_data;
	for (i = 0; i < GARMIN_CHANNELS; i++, sats++) {
	   display(mid114win, i + 2, 3,  " %3u %3u %2u %4.1f %2x",
		 sats->svid,
		 GPSD_LE16TOH(sats->azmth),
		 sats->elev,
		 (float)GPSD_LE16TOH(sats->snr) / 100.0,
		 sats->status);
	}
	monitor_log("SAT 0x%02x=", pkt_id);
	break;

    case 0xff:	/* Product Data Record */
	monitor_log("PDR 0x%02x=", pkt_id);
	break;

    default:
	monitor_log("UNK 0x%02x=", pkt_id);
	break;
    }
}
Exemple #4
0
void gpsd_time_init(struct gps_context_t *context, time_t starttime)
/* initialize the GPS context's time fields */
{
    /*
     * Provides a start time for getting the century.  Do this, just
     * in case one of our embedded deployments is still in place in
     * the year 2.1K.  Still likely to fail if we bring up the daemon
     * just before a century mark, but that case is probably doomed
     * anyhow because of 2-digit years.
     */
    context->leap_seconds = LEAPSECOND_NOW;
    context->century = CENTURY_BASE;
    context->start_time = starttime;

    context->rollovers = (int)((context->start_time-GPS_EPOCH) / GPS_ROLLOVER);

    if (context->start_time < GPS_EPOCH)
	gpsd_report(LOG_ERROR, "system time looks bogus, dates may not be reliable.\n");
    else {
	struct tm *now = localtime(&context->start_time);
	char scr[128];
	/*
	 * This is going to break our regression-test suite once a century.
	 * I think we can live with that consequence.
	 */
	now->tm_year += 1900;
	context->century = now->tm_year - (now->tm_year % 100);
	(void)unix_to_iso8601((timestamp_t)context->start_time, scr, sizeof(scr));
	gpsd_report(LOG_INF, "startup at %s (%d)\n", 
		    scr, (int)context->start_time);
    }
}
Exemple #5
0
/* This gets called once for each new compass sentence. */
static void update_compass_panel(struct gps_data_t *gpsdata)
{
    char scr[128];
    /* Print time/date. */
    if (isnan(gpsdata->fix.time) == 0) {
	(void)unix_to_iso8601(gpsdata->fix.time, scr, sizeof(scr));
    } else
	(void)snprintf(scr, sizeof(scr), "n/a");
    (void)mvwprintw(datawin, 1, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr);

    /* Fill in the heading. */
    if (isnan(gpsdata->fix.track) == 0) {
	(void)snprintf(scr, sizeof(scr), "%.1f degrees", gpsdata->fix.track);
    } else
	(void)snprintf(scr, sizeof(scr), "n/a");
    (void)mvwprintw(datawin, 2, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr);

    /* Fill in the pitch. */
    if (isnan(gpsdata->fix.climb) == 0) {
	(void)snprintf(scr, sizeof(scr), "%.1f", gpsdata->fix.climb);
    } else
	(void)snprintf(scr, sizeof(scr), "n/a");
    (void)mvwprintw(datawin, 3, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr);

    /* Fill in the roll. */
    if (isnan(gpsdata->fix.speed) == 0)
	(void)snprintf(scr, sizeof(scr), "%.1f", gpsdata->fix.speed);
    else
	(void)snprintf(scr, sizeof(scr), "n/a");
    (void)mvwprintw(datawin, 4, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr);

    /* Fill in the speed. */
    if (isnan(gpsdata->fix.altitude) == 0)
	(void)snprintf(scr, sizeof(scr), "%.1f", gpsdata->fix.altitude);
    else
	(void)snprintf(scr, sizeof(scr), "n/a");
    (void)mvwprintw(datawin, 5, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr);

    /* When we need to fill in receiver type again, do it here. */
    (void)mvwprintw(datawin, 6, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr);

    /* Be quiet if the user requests silence. */
    if (!silent_flag && raw_flag) {
	(void)waddstr(messages, message);
    }

    (void)wrefresh(datawin);
    if (raw_flag) {
	(void)wrefresh(messages);
    }
}
Exemple #6
0
static void print_gpx_header(void)
{
    char tbuf[CLIENT_DATE_MAX+1];

    (void)fprintf(logfile,"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
    (void)fprintf(logfile,"<gpx version=\"1.1\" creator=\"GPSD %s - %s\"\n", VERSION, GPSD_URL);
    (void)fprintf(logfile,"        xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n");
    (void)fprintf(logfile,"        xmlns=\"http://www.topografix.com/GPX/1/1\"\n");
    (void)fprintf(logfile,"        xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1\n");
    (void)fprintf(logfile,"        http://www.topografix.com/GPX/1/1/gpx.xsd\">\n");
    (void)fprintf(logfile," <metadata>\n");
    (void)fprintf(logfile,"  <time>%s</time>\n", unix_to_iso8601((timestamp_t)time(NULL), tbuf, sizeof(tbuf)));
    (void)fprintf(logfile," </metadata>\n");
    (void)fflush(logfile);
}
Exemple #7
0
// This is the main polling function
int GPScollectData() {

	char buffer[128];
	int readData;

	if (gps_waiting(&gpsdata, 1000000)) {  // Are there data ?
		readData = 0;
		readData = gps_read(&gpsdata);
        if (readData > 0) { // Read data
            if(gpsdata.online != 0) { // GPS not online
	            if(gpsdata.status != STATUS_NO_FIX) { // We have a fix point
					__recordStringValue("FIXED", "GPSstatus"); // set into DB
				    // gpsdata.satellites_used
					if( gpsdata.fix.mode ==  MODE_2D || gpsdata.fix.mode ==  MODE_3D) {
						unix_to_iso8601(gpsdata.fix.time, buffer, sizeof(buffer));
						__recordStringValue(buffer, "GPStime");
						__recordFloatValue(gpsdata.fix.latitude, "GPSlatit");
						__recordFloatValue(gpsdata.fix.longitude, "GPSlongi");
						sprintf(buffer,"{\n\"time\": %f,\n\"lat\": %f,\n\"lon\": %f\n}",gpsdata.fix.time, gpsdata.fix.latitude, gpsdata.fix.longitude);
						__recordStringValue(buffer, "GPSposition");
					}
					if( gpsdata.fix.mode ==  MODE_3D) {
						__recordFloatValue(gpsdata.fix.altitude, "GPSaltit");
						__recordFloatValue(gpsdata.fix.climb, "GPSclimb");
						__recordFloatValue(gpsdata.fix.speed, "GPSspeed");
						__recordFloatValue(gpsdata.fix.track, "GPStrack");
					}
				} else {
					__recordStringValue("FIXING", "GPSstatus");
				}
			} else {
				__recordStringValue("OFFLINE", "GPSstatus");
			}
        } else {
        	if( readData == 0 ) {
        		__recordStringValue("NODATA", "GPSstatus");
        		isGpsd = true;
        	} else {
        		__recordStringValue("NODEVICE", "GPSstatus");
        		isGpsd = false;
        	}
        }
    } else {
	//	__recordStringValue("NODATA", "GPSstatus");
		isGpsd = true;
    }
	return(RC_DATAVALID);
}
Exemple #8
0
static void gpsd_get_location(struct globals *globals)
{
	if (globals->source == SOURCE_CMDLINE) {
		char tbuf[JSON_DATE_MAX+1];
		timestamp_t now = timestamp();

		sprintf(globals->gpsd_data->tpv,
			"{\"class\":\"TPV\",\"device\":\"command line\","
			"\"time\":\"%s\","
			"\"lat\":%f,\"lon\":%f,\"alt\":%f,"
			"\"mode\":3}",
			unix_to_iso8601(now, tbuf, sizeof(tbuf)),
			globals->lat, globals->lon, globals->alt);
		globals->gpsd_data->tpv_len =
			htonl(strlen(globals->gpsd_data->tpv) + 1);
	}
}
Exemple #9
0
static void
print_fix(struct gps_data_t *gpsdata)
{
	struct gps_fix_t *fix = &gpsdata->fix;
	char tbuf[128];

	fprintf(logfile, "   <trkpt lat=\"%f\" lon=\"%f\">\n",
	    fix->latitude, fix->longitude);
	if (!isnan(fix->altitude))
		fprintf(logfile, "    <ele>%.f</ele>\n", fix->altitude);
	fprintf(logfile, "    <time>%s</time>\n", unix_to_iso8601(fix->time,
	    tbuf, sizeof(tbuf)));
	if (verbose) {
		switch (fix->mode) {
		case MODE_3D:
			fprintf(logfile, "    <fix>3d</fix>\n");
			break;
		case MODE_2D:
			fprintf(logfile, "    <fix>2d</fix>\n");
			break;
		case MODE_NO_FIX:
			fprintf(logfile, "    <fix>none</fix>\n");
			break;
		default:
			syslog(LOG_WARNING, "%s: unexpected fix %d", __func__,
			    fix->mode);
			break;
		}
		if (gpsdata->satellites_used > 0)
	    		fprintf(logfile, "    <sat>%d</sat>\n",
			    gpsdata->satellites_used);
		if (!isnan(gpsdata->dop.hdop))
			fprintf(logfile, "    <hdop>%.1f</hdop>\n",
			    gpsdata->dop.hdop);
		if (!isnan(gpsdata->dop.vdop))
			fprintf(logfile, "    <vdop>%.1f</vdop>\n",
			    gpsdata->dop.vdop);
		if (!isnan(gpsdata->dop.pdop))
			fprintf(logfile, "    <pdop>%.1f</pdop>\n",
			    gpsdata->dop.pdop);
	}
	fprintf(logfile, "   </trkpt>\n");
	fflush(logfile);
}
Exemple #10
0
void gpsd_time_init(struct gps_context_t *context, time_t starttime)
/* initialize the GPS context's time fields */
{
    /*
     * gpsd can't work with 'right' timezones (leapseconds inserted in
     * the timezone offset).  Avoid this and all manner of other local
     * time issues by telling the system we want times returned in UTC.
     */
    (void)putenv("TZ=UTC");

    /*
     * Provides a start time for getting the century.  Do this, just
     * in case one of our embedded deployments is still in place in
     * the year 2.1K.  Still likely to fail if we bring up the daemon
     * just before a century mark, but that case is probably doomed
     * anyhow because of 2-digit years.
     */
    context->leap_seconds = BUILD_LEAPSECONDS;
    context->century = BUILD_CENTURY;
    context->start_time = starttime;

    context->rollovers = (int)((context->start_time-GPS_EPOCH) / GPS_ROLLOVER);

    if (context->start_time < GPS_EPOCH)
	gpsd_log(&context->errout, LOG_ERROR,
		 "system time looks bogus, dates may not be reliable.\n");
    else {
	/* we've forced the UTC timezone, so this is actually UTC */
	struct tm *now = localtime(&context->start_time);
	char scr[128];
	/*
	 * This is going to break our regression-test suite once a century.
	 * I think we can live with that consequence.
	 */
	now->tm_year += 1900;
	context->century = now->tm_year - (now->tm_year % 100);
	(void)unix_to_iso8601((timestamp_t)context->start_time, scr, sizeof(scr));
	gpsd_log(&context->errout, LOG_INF,
		 "startup at %s (%d)\n",
		 scr, (int)context->start_time);
    }
}
Exemple #11
0
static void print_fix(struct gps_data_t *gpsdata, double time)
{
    char tbuf[CLIENT_DATE_MAX+1];

    (void)fprintf(logfile,"   <trkpt lat=\"%f\" lon=\"%f\">\n",
		 gpsdata->fix.latitude, gpsdata->fix.longitude);
    if ((isnan(gpsdata->fix.altitude) == 0))
	(void)fprintf(logfile,"    <ele>%f</ele>\n", gpsdata->fix.altitude);
    (void)fprintf(logfile,"    <time>%s</time>\n",
		 unix_to_iso8601(time, tbuf, sizeof(tbuf)));
    (void)fprintf(logfile,"    <src>GPSD tag=\"%s\"</src>\n", gpsdata->tag);
    if (gpsdata->status == STATUS_DGPS_FIX)
	(void)fprintf(logfile,"    <fix>dgps</fix>\n");
    else
	switch (gpsdata->fix.mode) {
	case MODE_3D:
	    (void)fprintf(logfile,"    <fix>3d</fix>\n");
	    break;
	case MODE_2D:
	    (void)fprintf(logfile,"    <fix>2d</fix>\n");
	    break;
	case MODE_NO_FIX:
	    (void)fprintf(logfile,"    <fix>none</fix>\n");
	    break;
	default:
	    /* don't print anything if no fix indicator */
	    break;
	}

    if ((gpsdata->fix.mode > MODE_NO_FIX) && (gpsdata->satellites_used > 0))
	(void)fprintf(logfile,"    <sat>%d</sat>\n", gpsdata->satellites_used);
    if (isnan(gpsdata->dop.hdop) == 0)
	(void)fprintf(logfile,"    <hdop>%.1f</hdop>\n", gpsdata->dop.hdop);
    if (isnan(gpsdata->dop.vdop) == 0)
	(void)fprintf(logfile,"    <vdop>%.1f</vdop>\n", gpsdata->dop.vdop);
    if (isnan(gpsdata->dop.pdop) == 0)
	(void)fprintf(logfile,"    <pdop>%.1f</pdop>\n", gpsdata->dop.pdop);

    (void)fprintf(logfile,"   </trkpt>\n");
    (void)fflush(logfile);
}
Exemple #12
0
static void sirf_update(void)
{
    int i, j, ch, sv;
    unsigned char *buf;
    size_t len;
    uint8_t dgps;
    char tbuf[JSON_DATE_MAX+1];

    buf = session.lexer.outbuffer + 4;
    len = session.lexer.outbuflen - 8;
    switch (buf[0]) {
    case 0x02:			/* Measured Navigation Data */
	(void)wmove(mid2win, 1, 6);	/* ECEF position */
	(void)wprintw(mid2win, "%8d %8d %8d", getbes32(buf, 1),
		      getbes32(buf, 5), getbes32(buf, 9));
	(void)wmove(mid2win, 2, 6);	/* ECEF velocity */
	(void)wprintw(mid2win, "%8.1f %8.1f %8.1f",
		      (double)getbes16(buf, 13) / 8, (double)getbes16(buf,
								    15) / 8,
		      (double)getbes16(buf, 17) / 8);
	decode_ecef((double)getbes32(buf, 1), (double)getbes32(buf, 5),
		    (double)getbes32(buf, 9), (double)getbes16(buf, 13) / 8,
		    (double)getbes16(buf, 15) / 8, (double)getbes16(buf,
								  17) / 8);
	/* line 3 */
	(void)wmove(mid2win, 3, 7);
	(void)wprintw(mid2win, "%-24s",
			unix_to_iso8601(session.gpsdata.fix.time, tbuf, sizeof(tbuf))
			);
	(void)wmove(mid2win, 3, 38);
	(void)wattrset(mid2win, A_UNDERLINE);
	if (ppstime_enabled)
	   (void)wprintw(mid2win, "%02d", leapseconds);
	else
	   (void)wprintw(mid2win, "??");
	(void)wattrset(mid2win, A_NORMAL);
	/* line 4 */
	/* HDOP */
	(void)wmove(mid2win, 4, 59);
	(void)wprintw(mid2win, "%4.1f", (double)getub(buf, 20) / 5);
	/* Mode 1 */
	(void)wmove(mid2win, 4, 69);
	(void)wprintw(mid2win, "%02x", getub(buf, 19));
	/* Mode 2 */
	(void)wmove(mid2win, 4, 77);
	(void)wprintw(mid2win, "%02x", getub(buf, 21));
	/* SVs in fix */
	(void)wmove(mid2win, 4, 6);
	(void)wprintw(mid2win, "%2d =                                     ",
		      (int)getub(buf, 28));
	/* SV list */
	(void)wmove(mid2win, 4, 10);
	/* coverity_submit[tainted_data] */
	for (i = 0; i < (int)getub(buf, 28); i++)
	   (void)wprintw(mid2win, " %2d", (int)getub(buf, 29 + i));
	monitor_log("MND 0x02=");
	break;

    case 0x04:			/* Measured Tracking Data */
	ch = (int)getub(buf, 7);
	for (i = 0; i < ch; i++) {
	    int az, el, state, off;
	    double cn;

	    off = 8 + 15 * i;
	    (void)wmove(mid4win, i + 2, 3);

	    sv = (int)getub(buf, off);
	    az = (int)getub(buf, off + 1) * 3 / 2;
	    el = (int)getub(buf, off + 2) / 2;
	    state = (int)getbeu16(buf, off + 3);
	    cn = 0;
	    for (j = 0; j < 10; j++)
		cn += (int)getub(buf, off + 5 + j);
	    cn /= 10;

	    (void)wprintw(mid4win, " %3d %3d %2d %04x %4.1f %c",
			   sv, az, el, state, cn, state == 0xbf ? 'T' : ' ');
	}
	monitor_log("MTD 0x04=");
	break;

#ifdef __UNUSED__
    case 0x05:			/* raw track data */
	for (off = 1; off < len; off += 51) {
	    ch = getbeu32(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", getbeu32(buf, off + 8),
		   (int)getbeu16(buf, off + 12), (int)getbeu16(buf, off + 14));
	    printw("%8.5f %10.5f", (double)getbeu32(buf, off + 16) / 65536,
		   (double)getbeu32(buf, off + 20) / 1024);
	}
	monitor_log("RTD 0x05=");
	break;
#endif /* __UNUSED */

    case 0x06:			/* firmware version */
	display(mid6win, 1, 1, "%s", buf + 1);
	monitor_log("FV  0x06=");
	break;

    case 0x07:			/* Response - Clock Status Data */
	display(mid7win, 1, 5, "%2d", getub(buf, 7));	/* SVs */
	display(mid7win, 1, 16, "%lu", getbeu32(buf, 8));	/* Clock ppstimes */
	display(mid7win, 1, 29, "%lu", getbeu32(buf, 12));	/* Clock Bias */
	display(mid7win, 2, 11, "%lu", getbeu32(buf, 16));	/* Estimated Time */
	monitor_log("CSD 0x07=");
	break;

    case 0x08:			/* 50 BPS data */
	ch = (int)getub(buf, 1);
	sv = (int)getub(buf, 2);
	display(mid4win, ch + 2, 27, "%2d", sv);
	subframe_enabled = true;
	monitor_log("50B 0x08=");
	break;

    case 0x09:			/* Throughput */
	display(mid9win, 1, 6, "%.3f", (double)getbeu16(buf, 1) / 186);	/*SegStatMax */
	display(mid9win, 1, 18, "%.3f", (double)getbeu16(buf, 3) / 186);	/*SegStatLat */
	display(mid9win, 1, 31, "%.3f", (double)getbeu16(buf, 5) / 186);	/*SegStatTime */
	display(mid9win, 1, 42, "%3d", (int)getbeu16(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, 1, "%02d =                                            ",
				 getub(buf, 1));
	(void)wmove(mid13win, 1, 5);
	for (i = 0; i < (int)getub(buf, 1); i++)
	    (void)wprintw(mid13win, " %d", getub(buf, 2 + 5 * i));
	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)getbeu16(buf, 7));	/* Alt. source input */
	if (getub(buf, 9) != (uint8_t) '\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)getbeu16(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", getbeu32(buf, 35));	/* LP On Time */
	display(mid19win, 3, 42, "%d", getbeu32(buf, 39));	/* LP Interval */
	display(mid19win, 4, 42, "%c", YESNO(43));	/* User Tasks enabled */
	display(mid19win, 5, 42, "%d", getbeu32(buf, 44));	/* User Task Interval */
	display(mid19win, 6, 42, "%c", YESNO(48));	/* LP Power Cycling Enabled */
	display(mid19win, 7, 42, "%d", getbeu32(buf, 49));	/* LP Max Acq Search Time */
	display(mid19win, 8, 42, "%d", getbeu32(buf, 53));	/* LP Max Off Time */
	display(mid19win, 9, 42, "%c", YESNO(57));	/* APM Enabled */
	display(mid19win, 10, 42, "%d", (int)getbeu16(buf, 58));	/* # of fixes */
	display(mid19win, 11, 42, "%d", (int)getbeu16(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
	monitor_log("NP  0x13=");
	break;

    case 0x1b:
	/******************************************************************
	 Not actually documented in any published materials before the
	 1.6 version of the SiRF binary protocol manual.
	 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
	******************************************************************/
	dgps = getub(buf, 1);
	display(mid27win, 1, 1, "%8s =                                      ",
		(CHECK_RANGE(dgpsvec, dgps) ? dgpsvec[dgps] : "???"));
	(void)wmove(mid27win, 1, 11);
	for (ch = 0; ch < SIRF_CHANNELS; ch++)
	    if (getub(buf, 16 + 3 * ch) != '\0')
		(void)wprintw(mid27win, " %d", getub(buf, 16 + 3 * ch));
	monitor_log("DST 0x1b=");
	break;

    case 0x1c:			/* NL Measurement Data */
    case 0x1d:			/* NL DGPS Data */
    case 0x1e:			/* NL SV State Data */
    case 0x1f:			/* NL Initialized Data */
	subframe_enabled = true;
	monitor_log("NL  0x%02x=", buf[0]);
	break;

    case 0x29:			/* Geodetic Navigation Data */
	monitor_log("GND 0x29=");
	break;

    case 0x32:			/* SBAS Parameters */
	monitor_log("SBP 0x32=");
	break;

    case 0x34:			/* PPS Time */
	ppstime_enabled = true;
	leapseconds = (int)getbeu16(buf, 8);
	monitor_log("PPS 0x34=");
	break;

    case 0xff:			/* Development Data */
	while (len > 0 && buf[len - 1] == '\n')
	    len--;
	while (len > 0 && buf[len - 1] == ' ')
	    len--;
	buf[len] = '\0';
	j = 1;
	for (i = 0; verbpat[i] != NULL; i++)
	    if (str_starts_with((char *)(buf + 1), verbpat[i])) {
		j = 0;
		break;
	    }
	if (j != 0)
	    monitor_log("%s\n", buf + 1);
	monitor_log("DD  0xff=");
	break;

    default:
	monitor_log("UNK 0x%02x=", buf[0]);
	break;
    }

#ifdef CONTROLSEND_ENABLE
    /* elicit navigation parameters */
    if (dispmode && (time(NULL) % 10 == 0)) {
	(void)monitor_control_send((unsigned char *)"\x98\x00", 2);
    }
#endif /* CONTROLSEND_ENABLE */

    /* clear the 50bps data field every 6 seconds */
    if (subframe_enabled && (time(NULL) % 6 == 0)) {
	for (ch = 0; ch < SIRF_CHANNELS; ch++)
	   display(mid4win, ch + 2, 27, "  ");
    }

    if (dispmode) {
	(void)touchwin(mid19win);
	(void)wnoutrefresh(mid19win);
    }

#ifdef PPS_ENABLE
    pps_update(mid7win, 2, 32);
#endif /* PPS_ENABLE */
}
Exemple #13
0
/* runs on each sentence */
static void
update_panel(struct gps_data_t *gpsdata, char *message, 
	size_t len UNUSED, int level UNUSED)
{
	unsigned int i;
	int newstate;
	XmString string[MAXCHANNELS + 1];
	char s[128], *latlon, *sp;

	/* the raw data sisplay */
	if (message[0] != '\0')
		while (isspace(*(sp = message + strlen(message) - 1)))
			*sp = '\0';
	XmTextFieldSetString(status, message);

	/* This is for the satellite status display */
	if (gpsdata->satellites) {
		string[0] = XmStringCreateSimple(
		    "PRN:   Elev:  Azim:  SNR:  Used:");
		for (i = 0; i < MAXCHANNELS; i++) {
			if (i < (unsigned int)gpsdata->satellites) {
				(void)snprintf(s, sizeof(s),  
				    " %3d    %2d    %3d    %2d      %c", 
				    gpsdata->PRN[i], gpsdata->elevation[i],
				    gpsdata->azimuth[i], gpsdata->ss[i],
				    gpsdata->used[i] ? 'Y' : 'N');
			} else
			    (void)strlcpy(s, "                  ", sizeof(s));
			string[i + 1] = XmStringCreateSimple(s);
		}
		XmListReplaceItemsPos(satellite_list, string,
		    (int)sizeof(string), 1);
#ifndef S_SPLINT_S
		for (i = 0; i < (sizeof(string)/sizeof(string[0])); i++)
			XmStringFree(string[i]);
#endif /* S_SPLINT_S */
	}

	/* here are the value fields */
	if (isnan(gpsdata->fix.time)==0) {
	    (void)unix_to_iso8601(gpsdata->fix.time, s, sizeof(s));
		XmTextFieldSetString(text_1, s);
	} else
		XmTextFieldSetString(text_1, "n/a");
	if (gpsdata->fix.mode >= MODE_2D) {
		latlon = deg_to_str(deg_type,
		    fabs(gpsdata->fix.latitude));
		(void)snprintf(s, sizeof(s), "%s %c", latlon,
		    (gpsdata->fix.latitude < 0) ? 'S' : 'N');
		XmTextFieldSetString(text_2, s);
	} else
		XmTextFieldSetString(text_2, "n/a");
	if (gpsdata->fix.mode >= MODE_2D) {
		latlon = deg_to_str(deg_type,
		    fabs(gpsdata->fix.longitude));
		(void)snprintf(s, sizeof(s), "%s %c", latlon,
		    (gpsdata->fix.longitude < 0) ? 'W' : 'E');
		XmTextFieldSetString(text_3, s);
	} else
		XmTextFieldSetString(text_3, "n/a");
	if (gpsdata->fix.mode == MODE_3D) {
		(void)snprintf(s, sizeof(s), "%f %s",
		    gpsdata->fix.altitude * altunits->factor,
		    altunits->legend);
		XmTextFieldSetString(text_4, s);
	} else
		XmTextFieldSetString(text_4, "n/a");
	if (gpsdata->fix.mode >= MODE_2D && isnan(gpsdata->fix.track)==0) {
		(void)snprintf(s, sizeof(s), "%f %s",
		    gpsdata->fix.speed * speedunits->factor,
		    speedunits->legend);
		XmTextFieldSetString(text_5, s);
	} else
		XmTextFieldSetString(text_5, "n/a");
	if (gpsdata->fix.mode >= MODE_2D && isnan(gpsdata->fix.track)==0) {
		(void)snprintf(s, sizeof(s), "%f degrees",
		    gpsdata->fix.track);
		XmTextFieldSetString(text_6, s);
	} else
		XmTextFieldSetString(text_6, "n/a");
	if (isnan(gpsdata->fix.eph)==0) {
		(void)snprintf(s, sizeof(s), "%f %s",
		    gpsdata->fix.eph * altunits->factor,
		    altunits->legend);
		XmTextFieldSetString(text_7, s);
	} else
		XmTextFieldSetString(text_7, "n/a");
	if (isnan(gpsdata->fix.epv)==0) {
		(void)snprintf(s, sizeof(s), "%f %s", 
		    gpsdata->fix.epv * altunits->factor,
		    altunits->legend);
		XmTextFieldSetString(text_8, s);
	} else
		XmTextFieldSetString(text_8, "n/a");
	if (gpsdata->fix.mode == MODE_3D && isnan(gpsdata->fix.climb)==0) {
		(void)snprintf(s, sizeof(s), "%f %s/sec", 
		    gpsdata->fix.climb * altunits->factor,
		    altunits->legend);
		XmTextFieldSetString(text_9, s);
	} else
		XmTextFieldSetString(text_9, "n/a");
	if (gpsdata->set & DEVICEID_SET) {
		(void)strlcpy(s, "xgps: ", sizeof(s));
		(void)strlcpy(s+6, gpsdata->gps_id, sizeof(s)-6);
		set_title(s);
	}
	if (gpsdata->online == 0) {
		newstate = 0;
		(void)strlcpy(s, "OFFLINE", sizeof(s));
	} else {
		newstate = gpsdata->fix.mode;

		switch (gpsdata->fix.mode) {
		case MODE_2D:
			(void)snprintf(s, sizeof(s), "2D %sFIX",
			    (gpsdata->status == STATUS_DGPS_FIX) ? "DIFF " :
			    "");
			break;
		case MODE_3D:
			(void)snprintf(s, sizeof(s), "3D %sFIX",
			    (gpsdata->status == STATUS_DGPS_FIX) ? "DIFF " :
			    "");
			break;
		default:
		    (void)strlcpy(s, "NO FIX", sizeof(s));
			break;
		}
	}
	if (newstate != state) {
		timer = time(NULL);
		state = newstate;
	}
	(void)snprintf(s + strlen(s), sizeof(s) - strlen(s), " (%d secs)",
	    (int) (time(NULL) - timer));
	XmTextFieldSetString(text_10, s);
	draw_graphics(gpsdata);

	XtRemoveTimeOut(timeout);
	timeout = XtAppAddTimeOut(app, 2000, handle_time_out, NULL);
}
Exemple #14
0
/*@-mustfreefresh@*/
static void update_gps_panel(struct gps_data_t *gpsdata)
/* This gets called once for each new GPS sentence. */
{
    int i;
    int newstate;
    char scr[128], *s;

    /* This is for the satellite status display.  Originally lifted from
     * xgps.c.  Note that the satellite list may be truncated based on
     * available screen size, or may only show satellites used for the
     * fix.  */
    if (gpsdata->satellites_visible != 0) {
	if (display_sats >= MAX_POSSIBLE_SATS) {
	    for (i = 0; i < MAX_POSSIBLE_SATS; i++) {
		if (i < gpsdata->satellites_visible) {
		    (void)snprintf(scr, sizeof(scr),
				   " %3d    %02d    %03d    %02d      %c",
				   gpsdata->skyview[i].PRN,
				   gpsdata->skyview[i].elevation,
				   gpsdata->skyview[i].azimuth,
				   (int)gpsdata->skyview[i].ss,
				   gpsdata->skyview[i].used ? 'Y' : 'N');
		} else {
		    (void)strlcpy(scr, "", sizeof(scr));
		}
		(void)mvwprintw(satellites, i + 2, 1, "%-*s",
				SATELLITES_WIDTH - 3, scr);
	    }
	} else {
	    int n = 0;
	    for (i = 0; i < MAX_POSSIBLE_SATS; i++) {
		if (n < display_sats) {
		    if ((i < gpsdata->satellites_visible)
			&& (gpsdata->skyview[i].used
			    || (gpsdata->satellites_visible <= display_sats))) {
			(void)snprintf(scr, sizeof(scr),
				       " %3d    %02d    %03d    %02d      %c",
				       gpsdata->skyview[i].PRN,
				       gpsdata->skyview[i].elevation,
				       gpsdata->skyview[i].azimuth,
				       (int)gpsdata->skyview[i].ss,
				       gpsdata->skyview[i].used ? 'Y' : 'N');
			(void)mvwprintw(satellites, n + 2, 1, "%-*s",
					SATELLITES_WIDTH - 3, scr);
			n++;
		    }
		}
	    }

	    if (n < display_sats) {
		for (i = n; i <= display_sats; i++) {
		    (void)mvwprintw(satellites, i + 2, 1, "%-*s",
				    SATELLITES_WIDTH - 3, "");
		}
	    }

	}
    }

    /* Print time/date. */
    if (isnan(gpsdata->fix.time) == 0) {
	(void)unix_to_iso8601(gpsdata->fix.time, scr, sizeof(scr));
    } else
	(void)snprintf(scr, sizeof(scr), "n/a");
    (void)mvwprintw(datawin, 1, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr);


    /* Fill in the latitude. */
    if (gpsdata->fix.mode >= MODE_2D && isnan(gpsdata->fix.latitude) == 0) {
	(void)snprintf(scr, sizeof(scr), "%s %c",
		       deg_to_str(deg_type, fabs(gpsdata->fix.latitude)),
		       (gpsdata->fix.latitude < 0) ? 'S' : 'N');
    } else
	(void)snprintf(scr, sizeof(scr), "n/a");
    (void)mvwprintw(datawin, 2, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr);

    /* Fill in the longitude. */
    if (gpsdata->fix.mode >= MODE_2D && isnan(gpsdata->fix.longitude) == 0) {
	(void)snprintf(scr, sizeof(scr), "%s %c",
		       deg_to_str(deg_type, fabs(gpsdata->fix.longitude)),
		       (gpsdata->fix.longitude < 0) ? 'W' : 'E');
    } else
	(void)snprintf(scr, sizeof(scr), "n/a");
    (void)mvwprintw(datawin, 3, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr);

    /* Fill in the altitude. */
    if (gpsdata->fix.mode >= MODE_3D && isnan(gpsdata->fix.altitude) == 0)
	(void)snprintf(scr, sizeof(scr), "%.1f %s",
		       gpsdata->fix.altitude * altfactor, altunits);
    else
	(void)snprintf(scr, sizeof(scr), "n/a");
    (void)mvwprintw(datawin, 4, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr);

    /* Fill in the speed. */
    if (gpsdata->fix.mode >= MODE_2D && isnan(gpsdata->fix.track) == 0)
	(void)snprintf(scr, sizeof(scr), "%.1f %s",
		       gpsdata->fix.speed * speedfactor, speedunits);
    else
	(void)snprintf(scr, sizeof(scr), "n/a");
    (void)mvwprintw(datawin, 5, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr);

    /* Fill in the heading. */
    if (gpsdata->fix.mode >= MODE_2D && isnan(gpsdata->fix.track) == 0) {
	double magheading = true2magnetic(gpsdata->fix.latitude,
					 gpsdata->fix.longitude,
					  gpsdata->fix.track);
	if (!magnetic_flag || isnan(magheading) != 0) {
	    (void)snprintf(scr, sizeof(scr), "%.1f deg (true)",
			   gpsdata->fix.track);
	} else {
	    (void)snprintf(scr, sizeof(scr), "%.1f deg (mag) ",
		magheading);
	}
    } else
	(void)snprintf(scr, sizeof(scr), "n/a");
    (void)mvwprintw(datawin, 6, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr);

    /* Fill in the rate of climb. */
    if (gpsdata->fix.mode >= MODE_3D && isnan(gpsdata->fix.climb) == 0)
	(void)snprintf(scr, sizeof(scr), "%.1f %s/min",
		       gpsdata->fix.climb * altfactor * 60, altunits);
    else
	(void)snprintf(scr, sizeof(scr), "n/a");
    (void)mvwprintw(datawin, 7, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr);

    /* Fill in the GPS status and the time since the last state
     * change. */
    if (gpsdata->online == 0) {
	newstate = 0;
	(void)snprintf(scr, sizeof(scr), "OFFLINE");
    } else {
	newstate = gpsdata->fix.mode;
	switch (gpsdata->fix.mode) {
	case MODE_2D:
	    (void)snprintf(scr, sizeof(scr), "2D %sFIX (%d secs)",
			   (gpsdata->status ==
			    STATUS_DGPS_FIX) ? "DIFF " : "",
			   (int)(time(NULL) - status_timer));
	    break;
	case MODE_3D:
	    (void)snprintf(scr, sizeof(scr), "3D %sFIX (%d secs)",
			   (gpsdata->status ==
			    STATUS_DGPS_FIX) ? "DIFF " : "",
			   (int)(time(NULL) - status_timer));
	    break;
	default:
	    (void)snprintf(scr, sizeof(scr), "NO FIX (%d secs)",
			   (int)(time(NULL) - status_timer));
	    break;
	}
    }
    (void)mvwprintw(datawin, 8, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr);

    /* Note that the following fields are exceptions to the
     * sizing rule.  The minimum window size does not include these
     * fields, if the window is too small, they get excluded.  This
     * may or may not change if/when the output for these fields is
     * fixed and/or people request their permanence.  They're only
     * there in the first place because I arbitrarily thought they
     * sounded interesting. ;^) */

    if (window_length >= (MIN_GPS_DATAWIN_SIZE + 5)) {

	/* Fill in the estimated horizontal position error. */
	if (isnan(gpsdata->fix.epx) == 0)
	    (void)snprintf(scr, sizeof(scr), "+/- %d %s",
			   (int)(gpsdata->fix.epx * altfactor), altunits);
	else
	    (void)snprintf(scr, sizeof(scr), "n/a");
	(void)mvwprintw(datawin, 9, DATAWIN_VALUE_OFFSET + 5, "%-*s", 22,
			scr);

	if (isnan(gpsdata->fix.epy) == 0)
	    (void)snprintf(scr, sizeof(scr), "+/- %d %s",
			   (int)(gpsdata->fix.epy * altfactor), altunits);
	else
	    (void)snprintf(scr, sizeof(scr), "n/a");
	(void)mvwprintw(datawin, 10, DATAWIN_VALUE_OFFSET + 5, "%-*s", 22,
			scr);

	/* Fill in the estimated vertical position error. */
	if (isnan(gpsdata->fix.epv) == 0)
	    (void)snprintf(scr, sizeof(scr), "+/- %d %s",
			   (int)(gpsdata->fix.epv * altfactor), altunits);
	else
	    (void)snprintf(scr, sizeof(scr), "n/a");
	(void)mvwprintw(datawin, 11, DATAWIN_VALUE_OFFSET + 5, "%-*s", 22,
			scr);

	/* Fill in the estimated track error. */
	if (isnan(gpsdata->fix.epd) == 0)
	    (void)snprintf(scr, sizeof(scr), "+/- %d deg",
			   (int)(gpsdata->fix.epd));
	else
	    (void)snprintf(scr, sizeof(scr), "n/a");
	(void)mvwprintw(datawin, 12, DATAWIN_VALUE_OFFSET + 5, "%-*s", 22,
			scr);

	/* Fill in the estimated speed error. */
	if (isnan(gpsdata->fix.eps) == 0)
	    (void)snprintf(scr, sizeof(scr), "+/- %d %s",
			   (int)(gpsdata->fix.eps * speedfactor), speedunits);
	else
	    (void)snprintf(scr, sizeof(scr), "n/a");
	(void)mvwprintw(datawin, 13, DATAWIN_VALUE_OFFSET + 5, "%-*s", 22,
			scr);
	/* Fill in the time offset. */
	if (isnan(gpsdata->fix.time) == 0)
	    (void)snprintf(scr, sizeof(scr), "%.3f",
			   (double)(timestamp()-gpsdata->fix.time));
	else
	    (void)snprintf(scr, sizeof(scr), "n/a");
	(void)mvwprintw(datawin, 14, DATAWIN_VALUE_OFFSET + 5, "%-*s", 22,
			scr);
	/* Fill in the grid square (esr thought *this* one was interesting). */
	/*@-branchstate@*/
	if (isnan(gpsdata->fix.longitude)==0 && isnan(gpsdata->fix.latitude)==0)
	    s = maidenhead(gpsdata->fix.latitude,gpsdata->fix.longitude);
	else
	    s = "n/a";
	(void)mvwprintw(datawin, 15, DATAWIN_VALUE_OFFSET + 5, "%-*s", 22, s);
	/*@+branchstate@*/
    }

    /* Be quiet if the user requests silence. */
    /*@-modobserver@*/
    if (!silent_flag && raw_flag && (s = (char *)gps_data(gpsdata)) != NULL) {
	char *p;
	for (p = s + strlen(s); --p > s && isspace(*p); *p = '\0')
	    ;
	(void)wprintw(messages, "%s\n", s);
    }
    /*@+modobserver@*/

    /* Reset the status_timer if the state has changed. */
    if (newstate != state) {
	status_timer = time(NULL);
	state = newstate;
    }

    (void)wrefresh(datawin);
    (void)wrefresh(satellites);
    if (raw_flag) {
	(void)wrefresh(messages);
    }
}