Exemplo n.º 1
0
static int ntrip_stream_req_probe(const struct ntrip_stream_t *stream,
				  struct gpsd_errout_t *errout)
{
    int dsock;
    ssize_t r;
    char buf[BUFSIZ];

    dsock = netlib_connectsock(AF_UNSPEC, stream->url, stream->port, "tcp");
    if (dsock < 0) {
	gpsd_log(errout, LOG_ERROR,
		 "ntrip stream connect error %d in req probe\n", dsock);
	return -1;
    }
    gpsd_log(errout, LOG_SPIN,
	     "ntrip stream for req probe connected on fd %d\n", dsock);
    (void)snprintf(buf, sizeof(buf),
	    "GET / HTTP/1.1\r\n"
	    "User-Agent: NTRIP gpsd/%s\r\n"
	    "Host: %s\r\n"
	    "Connection: close\r\n"
	    "\r\n", VERSION, stream->url);
    r = write(dsock, buf, strlen(buf));
    if (r != (ssize_t)strlen(buf)) {
	gpsd_log(errout, LOG_ERROR,
		 "ntrip stream write error %d on fd %d during probe request %zd\n",
		 errno, dsock, r);
	(void)close(dsock);
	return -1;
    }
    /* coverity[leaked_handle] This is an intentional allocation */
    return dsock;
}
Exemplo n.º 2
0
static gps_mask_t decode_itk_utcionomodel(struct gps_device_t *session,
					  unsigned char *buf, size_t len)
{
    int leap;
    unsigned short flags;

    if (len != 64) {
	gpsd_log(&session->context->errout, LOG_PROG,
		 "ITALK: bad UTC_IONO_MODEL (len %zu, should be 64)\n",
		 len);
	return 0;
    }

    flags = (unsigned short) getleu16(buf, 7);
    if (0 == (flags & UTC_IONO_MODEL_UTCVALID))
	return 0;

    leap = (int)getleu16(buf, 7 + 24);
    if (session->context->leap_seconds < leap)
	session->context->leap_seconds = leap;

    session->newdata.time = gpsd_gpstime_resolve(session,
	(unsigned short) getleu16(buf, 7 + 36),
	(unsigned int)getleu32(buf, 7 + 38)  / 1000.0);
    gpsd_log(&session->context->errout, LOG_DATA,
	     "UTC_IONO_MODEL: time=%.2f mask={TIME}\n",
	     session->newdata.time);
    return TIME_SET | NTPTIME_IS;
}
Exemplo n.º 3
0
static gps_mask_t decode_itk_subframe(struct gps_device_t *session,
				      unsigned char *buf, size_t len)
{
    unsigned short flags, prn, sf;
    unsigned int i;
    uint32_t words[10];

    if (len != 64) {
	gpsd_log(&session->context->errout, LOG_PROG,
		 "ITALK: bad SUBFRAME (len %zu, should be 64)\n", len);
	return 0;
    }

    flags = (unsigned short) getleu16(buf, 7 + 4);
    prn = (unsigned short) getleu16(buf, 7 + 6);
    sf = (unsigned short) getleu16(buf, 7 + 8);
    gpsd_log(&session->context->errout, LOG_PROG,
	     "iTalk 50B SUBFRAME prn %u sf %u - decode %s %s\n",
	     prn, sf,
	     (flags & SUBFRAME_WORD_FLAG_MASK) ? "error" : "ok",
	     (flags & SUBFRAME_GPS_PREAMBLE_INVERTED) ? "(inverted)" : "");
    if (flags & SUBFRAME_WORD_FLAG_MASK)
	return 0;	// don't try decode an erroneous packet

    /*
     * Timo says "SUBRAME message contains decoded navigation message subframe
     * words with parity checking done but parity bits still present."
     */
    for (i = 0; i < 10; i++)
	words[i] = (uint32_t)(getleu32(buf, 7 + 14 + 4 * i) >> 6) & 0xffffff;

    return gpsd_interpret_subframe(session, prn, words);
}
Exemplo n.º 4
0
static int ntrip_stream_get_req(const struct ntrip_stream_t *stream,
				const struct gpsd_errout_t *errout)
{
    int dsock;
    char buf[BUFSIZ];

    dsock = netlib_connectsock(AF_UNSPEC, stream->url, stream->port, "tcp");
    if (BAD_SOCKET(dsock)) {
	gpsd_log(errout, LOG_ERROR,
		 "ntrip stream connect error %d\n", dsock);
	return -1;
    }

    gpsd_log(errout, LOG_SPIN,
	     "netlib_connectsock() returns socket on fd %d\n",
	     dsock);

    (void)snprintf(buf, sizeof(buf),
	    "GET /%s HTTP/1.1\r\n"
	    "User-Agent: NTRIP gpsd/%s\r\n"
	    "Host: %s\r\n"
	    "Accept: rtk/rtcm, dgps/rtcm\r\n"
	    "%s"
	    "Connection: close\r\n"
	    "\r\n", stream->mountpoint, VERSION, stream->url, stream->authStr);
    if (write(dsock, buf, strlen(buf)) != (ssize_t) strlen(buf)) {
	gpsd_log(errout, LOG_ERROR,
		 "ntrip stream write error %d on fd %d during get request\n", errno,
		 dsock);
	(void)close(dsock);
	return -1;
    }
    return dsock;
}
Exemplo n.º 5
0
void ntrip_report(struct gps_context_t *context,
		  struct gps_device_t *gps,
		  struct gps_device_t *caster)
    /* may be time to ship a usage report to the Ntrip caster */
{
    static int count;
    /*
     * 10 is an arbitrary number, the point is to have gotten several good
     * fixes before reporting usage to our Ntrip caster.
     *
     * count % 5 is as arbitrary a number as the fixcnt. But some delay
     * was needed here
     */
    count ++;
    if (caster->ntrip.stream.nmea != 0 && context->fixcnt > 10 && (count % 5)==0) {
	if (caster->gpsdata.gps_fd > -1) {
	    char buf[BUFSIZ];
	    gpsd_position_fix_dump(gps, buf, sizeof(buf));
	    if (write(caster->gpsdata.gps_fd, buf, strlen(buf)) ==
		    (ssize_t) strlen(buf)) {
		gpsd_log(&context->errout, LOG_IO, "=> dgps %s\n", buf);
	    } else {
		gpsd_log(&context->errout, LOG_IO, "ntrip report write failed\n");
	    }
	}
    }
}
Exemplo n.º 6
0
bool shm_acquire(struct gps_context_t *context)
/* initialize the shared-memory segment to be used for export */
{
    /*@-nullpass@*/
    long shmkey = getenv("GPSD_SHM_KEY") ? strtol(getenv("GPSD_SHM_KEY"), NULL, 0) : GPSD_SHM_KEY;
    /*@+nullpass@*/

    int shmid = shmget((key_t)shmkey, sizeof(struct gps_data_t), (int)(IPC_CREAT|0666));
    if (shmid == -1) {
	gpsd_log(&context->errout, LOG_ERROR,
		 "shmget(0x%lx, %zd, 0666) for SHM export failed: %s\n",
		 shmkey,
		 sizeof(struct gps_data_t),
		 strerror(errno));
	return false;
    } else
	gpsd_log(&context->errout, LOG_PROG,
		 "shmget(0x%lx, %zd, 0666) for SHM export succeeded\n",
		 shmkey,
		 sizeof(struct gps_data_t));

    context->shmexport = (void *)shmat(shmid, 0, 0);
    if ((int)(long)context->shmexport == -1) {
	gpsd_log(&context->errout, LOG_ERROR,
		 "shmat failed: %s\n", strerror(errno));
	context->shmexport = NULL;
	return false;
    }
    gpsd_log(&context->errout, LOG_PROG,
	     "shmat() for SHM export succeeded, segment %d\n", shmid);
    return true;
}
Exemplo n.º 7
0
void dgpsip_report(struct gps_context_t *context,
		   struct gps_device_t *gps,
		   struct gps_device_t *dgpsip)
/* may be time to ship a usage report to the DGPSIP server */
{
    /*
     * 10 is an arbitrary number, the point is to have gotten several good
     * fixes before reporting usage to our DGPSIP server.
     */
    if (context->fixcnt > 10 && !dgpsip->dgpsip.reported) {
	dgpsip->dgpsip.reported = true;
	if (dgpsip->gpsdata.gps_fd > -1) {
	    char buf[BUFSIZ];
	    (void)snprintf(buf, sizeof(buf), "R %0.8f %0.8f %0.2f\r\n",
			   gps->gpsdata.fix.latitude,
			   gps->gpsdata.fix.longitude,
			   gps->gpsdata.fix.altitude);
	    if (write(dgpsip->gpsdata.gps_fd, buf, strlen(buf)) ==
		(ssize_t) strlen(buf))
		gpsd_log(&context->errout, LOG_IO, "=> dgps %s\n", buf);
	    else
		gpsd_log(&context->errout, LOG_IO, "write to dgps FAILED\n");
	}
    }
}
Exemplo n.º 8
0
static void onsig(int sig)
{
    if (sig == SIGALRM) {
	gpsd_log(&context.errout, LOG_ERROR, "packet recognition timed out.\n");
	exit(EXIT_FAILURE);
    } else {
	gpsd_log(&context.errout, LOG_ERROR, "killed by signal %d\n", sig);
	exit(EXIT_SUCCESS);
    }
}
Exemplo n.º 9
0
static gps_mask_t decode_itk_prnstatus(struct gps_device_t *session,
				       unsigned char *buf, size_t len)
{
    gps_mask_t mask;

    if (len < 62) {
	gpsd_log(&session->context->errout, LOG_PROG,
		 "ITALK: runt PRN_STATUS (len=%zu)\n", len);
	mask = 0;
    } else {
	unsigned int i, nsv, nchan, st;

	session->gpsdata.skyview_time = gpsd_gpstime_resolve(session,
	    (unsigned short)getleu16(buf, 7 + 4),
	    (unsigned int)getleu32(buf, 7 + 6) / 1000.0),
	gpsd_zero_satellites(&session->gpsdata);
	nchan = (unsigned int)getleu16(buf, 7 + 50);
	if (nchan > MAX_NR_VISIBLE_PRNS)
	    nchan = MAX_NR_VISIBLE_PRNS;
	for (i = st = nsv = 0; i < nchan; i++) {
	    unsigned int off = 7 + 52 + 10 * i;
	    unsigned short flags;
	    bool used;

	    flags = (unsigned short) getleu16(buf, off);
	    used = (bool)(flags & PRN_FLAG_USE_IN_NAV);
	    session->gpsdata.skyview[st].ss = (float)(getleu16(buf, off + 2) & 0xff);
	    session->gpsdata.skyview[st].PRN = (short)(getleu16(buf, off + 4) & 0xff);
	    session->gpsdata.skyview[st].elevation = (short)(getles16(buf, off + 6) & 0xff);
	    session->gpsdata.skyview[st].azimuth = (short)(getles16(buf, off + 8) & 0xff);
	    session->gpsdata.skyview[st].used = used;
	    if (session->gpsdata.skyview[st].PRN > 0) {
		st++;
		if (used)
		    nsv++;
	    }
	}
	session->gpsdata.satellites_visible = (int)st;
	session->gpsdata.satellites_used = (int)nsv;
	mask = USED_IS | SATELLITE_SET;;

	gpsd_log(&session->context->errout, LOG_DATA,
		 "PRN_STATUS: time=%.2f visible=%d used=%d mask={USED|SATELLITE}\n",
		 session->newdata.time,
		 session->gpsdata.satellites_visible,
		 session->gpsdata.satellites_used);
    }

    return mask;
}
Exemplo n.º 10
0
static int ntrip_stream_get_parse(const struct ntrip_stream_t *stream,
				  const int dsock, 
				  const struct gpsd_errout_t *errout)
{
/*@-nullpass@*/
    char buf[BUFSIZ];
    int opts;
    memset(buf, 0, sizeof(buf));
    while (read(dsock, buf, sizeof(buf) - 1) == -1) {
	if (errno == EINTR)
	    continue;
	gpsd_log(errout, LOG_ERROR, 
		 "ntrip stream read error %d on fd %d during get rsp\n", errno,
		 dsock);
	goto close;
    }

    /* parse 401 Unauthorized */
    /* coverity[string_null] - guaranteed terminated by the memset above */
    if (strstr(buf, NTRIP_UNAUTH)!=NULL) {
	gpsd_log(errout, LOG_ERROR,
		 "not authorized for Ntrip stream %s/%s\n", stream->url,
		 stream->mountpoint);
	goto close;
    }
    /* parse SOURCETABLE */
    if (strstr(buf, NTRIP_SOURCETABLE)!=NULL) {
	gpsd_log(errout, LOG_ERROR,
		 "Broadcaster doesn't recognize Ntrip stream %s:%s/%s\n",
		 stream->url, stream->port, stream->mountpoint);
	goto close;
    }
    /* parse ICY 200 OK */
    if (strstr(buf, NTRIP_ICY)==NULL) {
	gpsd_log(errout, LOG_ERROR,
		 "Unknown reply %s from Ntrip service %s:%s/%s\n", buf,
		 stream->url, stream->port, stream->mountpoint);
	goto close;
    }
    opts = fcntl(dsock, F_GETFL);

    if (opts >= 0)
	(void)fcntl(dsock, F_SETFL, opts | O_NONBLOCK);

    return dsock;
close:
    (void)close(dsock);
    return -1;
/*@+nullpass@*/
}
Exemplo n.º 11
0
/*
 * pretend to decode MID 0xE3, Beiduo D2 Subframe data
 *
 * from Beidou Standard BDS-SIS-ICD-2.0
 * D2, with the data rate of 500 bps, is broadcasted by the GEO satellites.
 *
 * len 31 bytes
 *
 */
static gps_mask_t sky_msg_E3(struct gps_device_t *session,
				  unsigned char *buf, size_t len)
{
    int i;
    unsigned int prn;   /* BeidouPS sat PRN 201-205 */
    unsigned int subf;  /* subframe 1-5 */
    /* the words are preprocessed, not raw, just the 28 bytes of data */
    uint8_t bytes[28];  /* raw data */

    if ( 31 != len)
	return 0;

    prn = (unsigned int)getub(buf, 1);
    subf = (unsigned int)getub(buf, 2);
    for ( i = 0; i < 28; i++ ) {
	bytes[i] = getub(buf, 3 + i);
    }

    /* extra guard prevents expensive hexdump calls */
    if (session->context->errout.debug >= LOG_PROG) {
	gpsd_log(&session->context->errout, LOG_PROG,
		 "Skytraq: Beidou D2 subframe PRN %d Subframe %d "
	         "length %zd byte:%s\n",
		 prn, subf,
		 len,
		 gpsd_hexdump(session->msgbuf, sizeof(session->msgbuf),
				 (char *)bytes, 28));
    }


    return ONLINE_SET;
}
Exemplo n.º 12
0
/*
 * decode MID 0xDC, Measurement Time
 *
 * 10 bytes
 */
static gps_mask_t sky_msg_DC(struct gps_device_t *session,
				  unsigned char *buf, size_t len)
{
    unsigned int iod;   /* Issue of data 0 - 255 */
    unsigned int wn;    /* week number 0 - 65535 */
    unsigned int tow;   /* receiver tow 0 - 604799999 in mS */
    unsigned int mp;    /* measurement period 1 - 1000 ms */
    /* calculated */
    double	f_tow;  /* tow in seconds */
    unsigned int msec;  /* mSec part of tow */

    if ( 10 != len)
	return 0;

    iod = (unsigned int)getub(buf, 1);
    wn = getbeu16(buf, 2);
    tow = getbeu32(buf, 4);
    f_tow = (double)(tow / 1000);
    msec = tow % 1000;
    mp = getbeu16(buf, 8);

    /* should this be newdata.skyview_time? */
    session->gpsdata.skyview_time = gpsd_gpstime_resolve(session, wn, f_tow );

    gpsd_log(&session->context->errout, LOG_DATA,
	     "Skytraq: MID 0xDC: iod=%u, wn=%u, tow=%u, mp=%u, t=%lld.%03u\n",
	     iod, wn, tow, mp,
	     (long long)session->gpsdata.skyview_time, msec);
    return 0;
}
Exemplo n.º 13
0
static bool evermore_nmea_config(struct gps_device_t *session, int mode)
/* mode = 0 : EverMore default */
/* mode = 1 : gpsd best */
/* mode = 2 : EverMore search, activate PEMT101 message */
{
    unsigned char tmp8;
    /*@ +charint */
    unsigned char evrm_nmeaout_config[] = {
	0x8e,			/*  0: msg ID, NMEA Message Control */
	0xff,			/*  1: NMEA sentence bitmask, GGA(0), GLL(1), GSA(2), GSV(3), ... */
	0x01,			/*  2: nmea checksum no(0), yes(1) */
	1,			/*  3: GPGGA, interval 0-255s */
	0,			/*  4: GPGLL, interval 0-255s */
	1,			/*  5: GPGSA, interval 0-255s */
	1,			/*  6: GPGSV, interval 0-255s */
	1,			/*  7: GPRMC, interval 0-255s */
	0,			/*  8: GPVTG, interval 0-255s */
	0,			/*  9: PEMT,101, interval 0-255s */
	0, 0, 0, 0, 0, 0,	/* 10-15: reserved */
    };
    /*@ -charint */
    gpsd_log(&session->context->errout, LOG_PROG,
	     "evermore_nmea_config(%d)\n", mode);
    /*@i1@*/ tmp8 = (mode == 1) ? 5 : 1;
    /* NMEA GPGSV, gpsd  */
    evrm_nmeaout_config[6] = tmp8;	/* GPGSV, 1s or 5s */
    /*@i1@*/ tmp8 = (mode == 2) ? 1 : 0;
    /* NMEA PEMT101 */
    evrm_nmeaout_config[9] = tmp8;	/* PEMT101, 1s or 0s */
    return (evermore_control_send(session, (char *)evrm_nmeaout_config,
				  sizeof(evrm_nmeaout_config)) != -1);
}
Exemplo n.º 14
0
static char *ntrip_field_iterate(char *start,
				 char *prev,
				 const char *eol,
				 const struct gpsd_errout_t *errout)
{
    char *s, *t, *u;

    if (start)
	s = start;
    else {
	if (!prev)
	    return NULL;
	s = prev + strlen(prev) + 1;
	if (s >= eol)
	    return NULL;
    }

    /* ignore any quoted ; chars as they are part of the field content */
    t = s;
    while ((u = strstr(t, NTRIP_QSC)))
	t = u + strlen(NTRIP_QSC);

    if ((t = strstr(t, ";")))
	*t = '\0';

    gpsd_log(errout, LOG_RAW, "Next Ntrip source table field %s\n", s);

    return s;
}
Exemplo n.º 15
0
void ntpshm_link_activate(struct gps_device_t *session)
/* set up ntpshm storage for a session */
{
    /* don't talk to NTP when we're running inside the test harness */
    if (session->sourcetype == source_pty)
	return;

    if (session->sourcetype != source_pps ) {
	/* allocate a shared-memory segment for "NMEA" time data */
	session->shm_clock = ntpshm_alloc(session->context);

	if (session->shm_clock == NULL) {
	    gpsd_log(&session->context->errout, LOG_WARN,
		     "NTP: ntpshm_alloc() failed\n");
	    return;
        }
    }

#if defined(PPS_ENABLE)
    if (session->sourcetype == source_usb
            || session->sourcetype == source_rs232
            || session->sourcetype == source_pps) {
	/* We also have the 1pps capability, allocate a shared-memory segment
	 * for the 1pps time data and launch a thread to capture the 1pps
	 * transitions
	 */
	if ((session->shm_pps = ntpshm_alloc(session->context)) == NULL) {
	    gpsd_log(&session->context->errout, LOG_WARN,
		     "PPS: ntpshm_alloc(1) failed\n");
	} else {
	    init_hook(session);
	    session->pps_thread.report_hook = report_hook;
	    /*
	     * The HAT kludge. If we're using the HAT GPS on a
	     * Raspberry Pi or a workalike like the ODROIDC2, and
	     * there is a static /dev/pps0, and we have access because
	     * we're root, assume we want to use KPPS.
	     */
	    if ((strcmp(session->pps_thread.devicename, MAGIC_HAT_GPS) == 0
		 || strcmp(session->pps_thread.devicename, MAGIC_LINK_GPS) == 0)
		&& access("/dev/pps0", R_OK | W_OK) == 0)
		session->pps_thread.devicename = "/dev/pps0";
	    pps_thread_activate(&session->pps_thread);
	}
    }
#endif /* PPS_ENABLE */
}
Exemplo n.º 16
0
/**
 * GPS Satellite Info
 */
static gps_mask_t
oncore_msg_svinfo(struct gps_device_t *session, unsigned char *buf,
		  size_t data_len)
{
    unsigned int i, nchan;
    int j;

    if (data_len != 92)
	return 0;

    gpsd_log(&session->context->errout, LOG_DATA,
	     "oncore SVINFO - satellite data\n");
    nchan = (unsigned int)getub(buf, 4);
    gpsd_log(&session->context->errout, LOG_DATA,
	     "oncore SVINFO - %d satellites:\n", nchan);
    /* Then we clamp the value to not read outside the table. */
    if (nchan > 12)
	nchan = 12;
    session->driver.oncore.visible = (int)nchan;
    for (i = 0; i < nchan; i++) {
	/* get info for one channel/satellite */
	unsigned int off = 5 + 7 * i;

	int sv = (int)getub(buf, off);
	int el = (int)getub(buf, off + 3);
	int az = (int)getbeu16(buf, off + 4);

	gpsd_log(&session->context->errout, LOG_DATA,
		 "%2d %2d %2d %3d\n", i, sv, el, az);

	/* Store for use when Ea messages come. */
	session->driver.oncore.PRN[i] = sv;
	session->driver.oncore.elevation[i] = el;
	session->driver.oncore.azimuth[i] = az;
	/* If it has an entry in the satellite list, update it! */
	for (j = 0; j < session->gpsdata.satellites_visible; j++)
	    if (session->gpsdata.skyview[j].PRN == (short)sv) {
		session->gpsdata.skyview[j].elevation = (short)el;
		session->gpsdata.skyview[j].azimuth = (short)az;
	    }
    }

    gpsd_log(&session->context->errout, LOG_DATA,
	     "SVINFO: mask={SATELLITE}\n");
    return SATELLITE_SET;
}
Exemplo n.º 17
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);
    }
}
Exemplo n.º 18
0
bool gpsd_set_raw(struct gps_device_t * session)
{
    (void)cfmakeraw(&session->ttyset);
    if (tcsetattr(session->gpsdata.gps_fd, TCIOFLUSH, &session->ttyset) == -1) {
	gpsd_log(&session->context->errout, LOG_ERROR,
		 "error changing port attributes: %s\n", strerror(errno));
	return false;
    }

    return true;
}
Exemplo n.º 19
0
int dgpsip_open(struct gps_device_t *device, const char *dgpsserver)
/* open a connection to a DGPSIP server */
{
    char *colon, *dgpsport = "rtcm-sc104";
    int opts;

    device->dgpsip.reported = false;
    if ((colon = strchr(dgpsserver, ':')) != NULL) {
	dgpsport = colon + 1;
	*colon = '\0';
    }
    if (!getservbyname(dgpsport, "tcp"))
	dgpsport = DEFAULT_RTCM_PORT;

    device->gpsdata.gps_fd =
	netlib_connectsock(AF_UNSPEC, dgpsserver, dgpsport, "tcp");
    // cppcheck-suppress pointerPositive
    if (device->gpsdata.gps_fd >= 0) {
	char hn[256], buf[BUFSIZ];
	gpsd_log(&device->context->errout, LOG_PROG,
		 "connection to DGPS server %s established.\n",
		 dgpsserver);
	(void)gethostname(hn, sizeof(hn));
	/* greeting required by some RTCM104 servers; others will ignore it */
	(void)snprintf(buf, sizeof(buf), "HELO %s gpsd %s\r\nR\r\n", hn,
		       VERSION);
	if (write(device->gpsdata.gps_fd, buf, strlen(buf)) != (ssize_t) strlen(buf))
	    gpsd_log(&device->context->errout, LOG_ERROR,
		     "hello to DGPS server %s failed\n",
		     dgpsserver);
    } else
	gpsd_log(&device->context->errout, LOG_ERROR,
		 "can't connect to DGPS server %s, netlib error %d.\n",
		 dgpsserver, device->gpsdata.gps_fd);
    opts = fcntl(device->gpsdata.gps_fd, F_GETFL);

    if (opts >= 0)
	(void)fcntl(device->gpsdata.gps_fd, F_SETFL, opts | O_NONBLOCK);
    device->servicetype = service_dgpsip;
    return device->gpsdata.gps_fd;
}
Exemplo n.º 20
0
static volatile struct shmTime *getShmTime(struct gps_context_t *context, int unit)
{
    int shmid;
    unsigned int perms;
    volatile struct shmTime *p;
    // set the SHM perms the way ntpd does
    if (unit < 2) {
	// we are root, be careful
	perms = 0600;
    } else {
	// we are not root, try to work anyway
	perms = 0666;
    }

    /*
     * Note: this call requires root under BSD, and possibly on
     * well-secured Linux systems.  This is why ntpshm_context_init() has to be
     * called before privilege-dropping.
     */
    shmid = shmget((key_t) (NTPD_BASE + unit),
		   sizeof(struct shmTime), (int)(IPC_CREAT | perms));
    if (shmid == -1) {
	gpsd_log(&context->errout, LOG_ERROR,
		 "NTP: shmget(%ld, %zd, %o) fail: %s\n",
		 (long int)(NTPD_BASE + unit), sizeof(struct shmTime),
		 (int)perms, strerror(errno));
	return NULL;
    }
    p = (struct shmTime *)shmat(shmid, 0, 0);
    if ((int)(long)p == -1) {
	gpsd_log(&context->errout, LOG_ERROR,
		 "NTP: shmat failed: %s\n",
		 strerror(errno));
	return NULL;
    }
    gpsd_log(&context->errout, LOG_PROG,
	     "NTP: shmat(%d,0,0) succeeded, segment %d\n",
	     shmid, unit);
    return p;
}
Exemplo n.º 21
0
static gps_mask_t decode_itk_pseudo(struct gps_device_t *session,
				      unsigned char *buf, size_t len)
{
    unsigned short flags, n, i;

    n = (unsigned short) getleu16(buf, 7 + 4);
    if ((n < 1) || (n > MAXCHANNELS)){
	gpsd_log(&session->context->errout, LOG_INF,
		 "ITALK: bad PSEUDO channel count\n");
	return 0;
    }

    if (len != (size_t)((n+1)*36)) {
	gpsd_log(&session->context->errout, LOG_PROG,
		 "ITALK: bad PSEUDO len %zu\n", len);
    }

    gpsd_log(&session->context->errout, LOG_PROG, "iTalk PSEUDO [%u]\n", n);
    flags = (unsigned short)getleu16(buf, 7 + 6);
    if ((flags & 0x3) != 0x3)
	return 0; // bail if measurement time not valid.

    session->newdata.time = gpsd_gpstime_resolve(session,
						 (unsigned short int)getleu16((char *)buf, 7 + 8),
	(unsigned int)getleu32(buf, 7 + 38) / 1000.0);

    for (i = 0; i < n; i++){
	session->gpsdata.skyview[i].PRN = getleu16(buf, 7 + 26 + (i*36)) & 0xff;
	session->gpsdata.skyview[i].ss = getleu16(buf, 7 + 26 + (i*36 + 2)) & 0x3f;
	session->gpsdata.raw.satstat[i] = getleu32(buf, 7 + 26 + (i*36 + 4));
	session->gpsdata.raw.pseudorange[i] = getled64((char *)buf, 7 + 26 + (i*36 + 8));
	session->gpsdata.raw.doppler[i] = getled64((char *)buf, 7 + 26 + (i*36 + 16));
	session->gpsdata.raw.carrierphase[i] = getleu16(buf, 7 + 26 + (i*36 + 28));

	session->gpsdata.raw.mtime[i] = session->newdata.time;
	session->gpsdata.raw.codephase[i] = NAN;
	session->gpsdata.raw.deltarange[i] = NAN;
    }
    return RAW_IS;
}
Exemplo n.º 22
0
int ntpshm_put(struct gps_device_t *session, volatile struct shmTime *shmseg, struct timedelta_t *td)
/* put a received fix time into shared memory for NTP */
{
    char real_str[TIMESPEC_LEN];
    char clock_str[TIMESPEC_LEN];

    /* Any NMEA will be about -1 or -2. Garmin GPS-18/USB is around -6 or -7. */
    int precision = -20; /* default precision, 1 micro sec */

    if (shmseg == NULL) {
	gpsd_log(&session->context->errout, LOG_RAW, "NTP:PPS: missing shm\n");
	return 0;
    }

#ifdef PPS_ENABLE
    if (shmseg == session->shm_pps) {
        /* precision is a floor so do not make it tight */
        if ( source_usb == session->sourcetype ) {
	    /* if PPS over USB, then precision = -20, 1 micro sec  */
	    precision = -20;
        } else {
	    /* likely PPS over serial, precision = -30, 1 nano sec */
	    precision = -30;
        }
    }
#endif	/* PPS_ENABLE */

    ntp_write(shmseg, td, precision, session->context->leap_notify);

    timespec_str( &td->real, real_str, sizeof(real_str) );
    timespec_str( &td->clock, clock_str, sizeof(clock_str) );
    gpsd_log(&session->context->errout, LOG_PROG,
	     "NTP: ntpshm_put(%s,%s) %s @ %s\n",
	     session->gpsdata.dev.path,
	     precision,
	     real_str, clock_str);

    return 1;
}
Exemplo n.º 23
0
/**************************************************************************
 * decode integer from string, check if the result is in expected range
 * return 0: OK
 *       -1: data error
 *       -2: data not valid
**************************************************************************/
static int gar_int_decode(const struct gps_context_t *context,
			  const char *data, const size_t length,
			  const unsigned int min, const unsigned int max,
			  unsigned int *result)
{
    char buf[6];
    unsigned int res;

    if (length >= sizeof(buf)) {
	gpsd_log(&context->errout, LOG_ERROR, "internal buffer too small\n");
	return -1;
    }

    memset(buf, 0, (int)sizeof(buf));
    (void)strlcpy(buf, data, length);
    gpsd_log(&context->errout, LOG_RAW + 2, "Decoded string: %s\n", buf);

    if (strchr(buf, '_') != NULL) {
	/* value is not valid, ignore it */
	return -2;
    }

    if (strspn(buf, "0123456789") != length) {
	gpsd_log(&context->errout, LOG_WARN, "Invalid value %s\n", buf);
	return -1;
    }

    res = (unsigned)atoi(buf);
    if ((res >= min) && (res <= max)) {
	*result = res;
	return 0;		/* SUCCESS */
    } else {
	gpsd_log(&context->errout, LOG_WARN,
		 "Value %u out of range <%u, %u>\n", res, min,
		 max);
	return -1;
    }
}
Exemplo n.º 24
0
/*
 * decode MID 0xDD, Raw Measurements
 *
 */
static gps_mask_t sky_msg_DD(struct gps_device_t *session,
				  unsigned char *buf, size_t len UNUSED)
{
    unsigned int iod;   /* Issue of data 0 - 255 */
    unsigned int nmeas; /* number of measurements */

    iod = (unsigned int)getub(buf, 1);
    nmeas = (unsigned int)getub(buf, 2);

    gpsd_log(&session->context->errout, LOG_DATA,
	     "Skytraq: MID 0xDD: iod=%u, nmeas=%u\n",
	     iod, nmeas);
    return 0;
}
Exemplo n.º 25
0
/* zodiac_spew - Takes a message type, an array of data words, and a length
 * for the array, and prepends a 5 word header (including checksum).
 * The data words are expected to be checksummed.
 */
static ssize_t zodiac_spew(struct gps_device_t *session, unsigned short type,
			   unsigned short *dat, int dlen)
{
    struct header h;
    int i;
    char buf[BUFSIZ];

    h.sync = 0x81ff;
    h.id = (unsigned short)type;
    h.ndata = (unsigned short)(dlen - 1);
    h.flags = 0;
    h.csum = zodiac_checksum((unsigned short *)&h, 4);

    if (!BAD_SOCKET(session->gpsdata.gps_fd)) {
	size_t hlen, datlen;
	hlen = sizeof(h);
	datlen = sizeof(unsigned short) * dlen;
	if (end_write(session->gpsdata.gps_fd, &h, hlen) != (ssize_t) hlen ||
	    end_write(session->gpsdata.gps_fd, dat,
		      datlen) != (ssize_t) datlen) {
	    gpsd_log(&session->context->errout, LOG_RAW,
		     "Reconfigure write failed\n");
	    return -1;
	}
    }

    (void)snprintf(buf, sizeof(buf),
		   "%04x %04x %04x %04x %04x",
		   h.sync, h.id, h.ndata, h.flags, h.csum);
    for (i = 0; i < dlen; i++)
	str_appendf(buf, sizeof(buf), " %04x", dat[i]);

    gpsd_log(&session->context->errout, LOG_RAW,
	     "Sent Zodiac packet: %s\n", buf);

    return 0;
}
Exemplo n.º 26
0
static gps_mask_t handle1003(struct gps_device_t *session)
/* skyview report */
{
    int i, n;

    /* The Polaris (and probably the DAGR) emit some strange variant of
     * this message which causes gpsd to crash filtering on impossible
     * number of satellites avoids this */
    n = (int)getzword(14);
    if ((n < 0) || (n > 12))
	return 0;

    gpsd_zero_satellites(&session->gpsdata);

    /* ticks              = getzlong(6); */
    /* sequence           = getzword(8); */
    session->gpsdata.dop.gdop = (unsigned int)getzword(9) * 1e-2;
    session->gpsdata.dop.pdop = (unsigned int)getzword(10) * 1e-2;
    session->gpsdata.dop.hdop = (unsigned int)getzword(11) * 1e-2;
    session->gpsdata.dop.vdop = (unsigned int)getzword(12) * 1e-2;
    session->gpsdata.dop.tdop = (unsigned int)getzword(13) * 1e-2;
    session->gpsdata.satellites_visible = n;

    for (i = 0; i < ZODIAC_CHANNELS; i++) {
	if (i < session->gpsdata.satellites_visible) {
	    session->gpsdata.skyview[i].PRN = (short)getzword(15 + (3 * i));
	    session->gpsdata.skyview[i].azimuth =
		(short)(((short)getzword(16 + (3 * i))) * RAD_2_DEG * 1e-4);
	    if (session->gpsdata.skyview[i].azimuth < 0)
		session->gpsdata.skyview[i].azimuth += 360;
	    session->gpsdata.skyview[i].elevation =
		(short)(((short)getzword(17 + (3 * i))) * RAD_2_DEG * 1e-4);
	} else {
	    session->gpsdata.skyview[i].PRN = 0;
	    session->gpsdata.skyview[i].azimuth = 0;
	    session->gpsdata.skyview[i].elevation = 0;
	}
    }
    session->gpsdata.skyview_time = NAN;
    gpsd_log(&session->context->errout, LOG_DATA,
	     "NAVDOP: visible=%d gdop=%.2f pdop=%.2f "
	     "hdop=%.2f vdop=%.2f tdop=%.2f mask={SATELLITE|DOP}\n",
	     session->gpsdata.satellites_visible,
	     session->gpsdata.dop.gdop,
	     session->gpsdata.dop.hdop,
	     session->gpsdata.dop.vdop,
	     session->gpsdata.dop.pdop, session->gpsdata.dop.tdop);
    return SATELLITE_SET | DOP_SET;
}
Exemplo n.º 27
0
static void init_hook(struct gps_device_t *session)
/* for chrony SOCK interface, which allows nSec timekeeping */
{
    /* open the chrony socket */
    char chrony_path[GPS_PATH_MAX];

    session->chronyfd = -1;
    if ( 0 == getuid() ) {
	/* this case will fire on command-line devices;
	 * they're opened before priv-dropping.  Matters because
         * only root can use /var/run.
	 */
	(void)snprintf(chrony_path, sizeof (chrony_path),
		"/var/run/chrony.%s.sock", basename(session->gpsdata.dev.path));
    } else {
	(void)snprintf(chrony_path, sizeof (chrony_path),
		"/tmp/chrony.%s.sock", 	basename(session->gpsdata.dev.path));
    }

    if (access(chrony_path, F_OK) != 0) {
	gpsd_log(&session->context->errout, LOG_PROG,
		"PPS:%s chrony socket %s doesn't exist\n",
		session->gpsdata.dev.path, chrony_path);
    } else {
	session->chronyfd = netlib_localsocket(chrony_path, SOCK_DGRAM);
	if (session->chronyfd < 0)
	    gpsd_log(&session->context->errout, LOG_PROG,
		     "PPS:%s connect chrony socket failed: %s, error: %d, errno: %d/%s\n",
		     session->gpsdata.dev.path,
		     chrony_path, session->chronyfd, errno, strerror(errno));
	else
	    gpsd_log(&session->context->errout, LOG_RAW,
		     "PPS:%s using chrony socket: %s\n",
		     session->gpsdata.dev.path, chrony_path);
    }
}
Exemplo n.º 28
0
/**
 * PPS offset
 */
static gps_mask_t
oncore_msg_pps_offset(struct gps_device_t *session, unsigned char *buf,
		      size_t data_len)
{
    int pps_offset_ns;

    if (data_len != 11)
	return 0;

    gpsd_log(&session->context->errout, LOG_DATA, "oncore PPS offset\n");
    pps_offset_ns = (int)getbes32(buf, 4);

    session->driver.oncore.pps_offset_ns = pps_offset_ns;
    return 0;
}
Exemplo n.º 29
0
static void evermore_mode(struct gps_device_t *session, int mode)
{
    gpsd_log(&session->context->errout, LOG_PROG,
	     "evermore_mode(%d), %d\n", mode,
	     session->back_to_nmea ? 1 : 0);
    if (mode == MODE_NMEA) {
	/* NMEA */
	(void)evermore_protocol(session, 1);
	(void)evermore_nmea_config(session, 1);	/* configure NMEA messages for gpsd */
    } else {
	/* binary */
	(void)evermore_protocol(session, 0);
	session->back_to_nmea = false;
    }
}
Exemplo n.º 30
0
void gpsd_century_update(struct gps_device_t *session, int century)
{
    session->context->valid |= CENTURY_VALID;
    if (century > session->context->century) {
	/*
	 * This mismatch is almost certainly not due to a GPS week
	 * rollover, because that would throw the ZDA report backward
	 * into the last rollover period instead of forward.  Almost
	 * certainly it means that a century mark has passed while
	 * gpsd was running, and we should trust the new ZDA year.
	 */
	gpsd_log(&session->context->errout, LOG_WARN,
		 "century rollover detected.\n");
	session->context->century = century;
    } else if (session->context->start_time >= GPS_EPOCH && century < session->context->century) {
	/*
	 * This looks like a GPS week-counter rollover.
	 */
	gpsd_log(&session->context->errout, LOG_WARN,
		 "ZDA year less than clock year, "
		 "probable GPS week rollover lossage\n");
	session->context->valid &=~ CENTURY_VALID;
    }
}