Ejemplo n.º 1
0
/** @fn static void vehicle_file_close(struct vehicle_priv *priv)
*****************************************************************************
* @b Description: close dialogue with the GPS
*****************************************************************************
* @param      priv : pointer on the private data of the plugin
*****************************************************************************
**/
static void
vehicle_file_close(struct vehicle_priv *priv)
{
    dbg(1, "enter, priv->fd='%d'\n", priv->fd);
	vehicle_file_disable_watch(priv);
#ifdef _WIN32
    if(priv->file_type == file_type_serial)
    {
        if (priv->timeout_callback) {
   		callback_destroy(priv->timeout_callback);
		priv->timeout_callback=NULL;	// dangling pointer! prevent double freeing.
        }
	serial_io_shutdown( priv->fd );
    }
    else
#endif
    {
	if (priv->file) {
#ifndef _MSC_VER
		pclose(priv->file);
#endif /* _MSC_VER */
    }
	else if (priv->fd >= 0) {
		close(priv->fd);
    }
	priv->file = NULL;
	priv->fd = -1;
    }
}
Ejemplo n.º 2
0
/** @fn static void vehicle_file_io(struct vehicle_priv *priv)
*****************************************************************************
* @b Description: function to get data from GPS
*****************************************************************************
* @param      priv : pointer on the private data of the plugin
*****************************************************************************
* @remarks Not used on WIN32 operating system
*****************************************************************************
**/
static void
vehicle_file_io(struct vehicle_priv *priv)
{
	dbg(1, "vehicle_file_io : enter\n");
#ifndef _WIN32
	int size, rc = 0;
	char *str, *tok;

	size = read(priv->fd, priv->buffer + priv->buffer_pos, buffer_size - priv->buffer_pos - 1);
	if (size <= 0) {
		switch (priv->on_eof) {
		case 0:
			vehicle_file_close(priv);
			vehicle_file_open(priv);
			break;
		case 1:
			vehicle_file_disable_watch(priv);
			break;
		case 2:
			exit(0);
			break;
		}
		return;
	}
	priv->buffer_pos += size;
	priv->buffer[priv->buffer_pos] = '\0';
	dbg(1, "size=%d pos=%d buffer='%s'\n", size,
	    priv->buffer_pos, priv->buffer);
	str = priv->buffer;
	while ((tok = strchr(str, '\n'))) {
		*tok++ = '\0';
		dbg(1, "line='%s'\n", str);
		rc +=vehicle_file_parse(priv, str);
		str = tok;
	}

	if (str != priv->buffer) {
		size = priv->buffer + priv->buffer_pos - str;
		memmove(priv->buffer, str, size + 1);
		priv->buffer_pos = size;
		dbg(1, "now pos=%d buffer='%s'\n",
		    priv->buffer_pos, priv->buffer);
	} else if (priv->buffer_pos == buffer_size - 1) {
		dbg(0,
		    "Overflow. Most likely wrong baud rate or no nmea protocol\n");
		priv->buffer_pos = 0;
	}
	if (rc)
		callback_list_call_attr_0(priv->cbl, attr_position_coord_geo);
#endif
}
Ejemplo n.º 3
0
/** @fn static void vehicle_file_close(struct vehicle_priv *priv)
*****************************************************************************
* @b Description: close dialogue with the GPS
*****************************************************************************
* @param      priv : pointer on the private data of the plugin
*****************************************************************************
**/
static void
vehicle_file_close(struct vehicle_priv *priv)
{
    dbg(1, "enter, priv->fd='%d'\n", priv->fd);
	vehicle_file_disable_watch(priv);
#ifdef _WIN32
    if (priv->timeout_callback) {
   		callback_destroy(priv->timeout_callback);
		priv->timeout_callback=NULL;	// dangling pointer! prevent double freeing.
    }
	serial_io_shutdown( priv->fd );
#else
	if (priv->file)
		pclose(priv->file);
	else if (priv->fd >= 0)
		close(priv->fd);
	priv->file = NULL;
#endif
	priv->fd = -1;
}
Ejemplo n.º 4
0
/** @fn static int vehicle_file_parse( struct vehicle_priv *priv,
*                                      char *buffer)
*****************************************************************************
* @b Description: Parse the buffer
*****************************************************************************
* @param      priv : pointer on the private data of the plugin
* @param      buffer : data buffer (null terminated)
*****************************************************************************
* @return     1 if The GPRMC Sentence is found
*             0 if not found
*****************************************************************************
**/
static int
vehicle_file_parse(struct vehicle_priv *priv, char *buffer)
{
	char *nmea_data_buf, *p, *item[32];
	double lat, lng;
	int i, j, bcsum;
	int len = strlen(buffer);
	unsigned char csum = 0;
	int valid=0;
	int ret = 0;

	dbg(2, "enter: buffer='%s'\n", buffer);
	for (;;) {
		if (len < 4) {
			dbg(0, "'%s' too short\n", buffer);
			return ret;
		}
		if (buffer[len - 1] == '\r' || buffer[len - 1] == '\n') {
			buffer[--len] = '\0';
            if (buffer[len - 1] == '\r')
                buffer[--len] = '\0';
        } else
			break;
	}
	if (buffer[0] != '$') {
		dbg(0, "no leading $ in '%s'\n", buffer);
		return ret;
	}
	if (buffer[len - 3] != '*') {
		dbg(0, "no *XX in '%s'\n", buffer);
		return ret;
	}
	for (i = 1; i < len - 3; i++) {
		csum ^= (unsigned char) (buffer[i]);
	}
	if (!sscanf(buffer + len - 2, "%x", &bcsum) && priv->checksum_ignore != 2) {
		dbg(0, "no checksum in '%s'\n", buffer);
		return ret;
	}
	if (bcsum != csum && priv->checksum_ignore == 0) {
		dbg(0, "wrong checksum in '%s'\n", buffer);
		return ret;
	}

	if (!priv->nmea_data_buf || strlen(priv->nmea_data_buf) < 65536) {
		nmea_data_buf=g_strconcat(priv->nmea_data_buf ? priv->nmea_data_buf : "", buffer, "\n", NULL);
		g_free(priv->nmea_data_buf);
		priv->nmea_data_buf=nmea_data_buf;
	} else {
		dbg(0, "nmea buffer overflow, discarding '%s'\n", buffer);
	}
	i = 0;
	p = buffer;
	while (i < 31) {
		item[i++] = p;
		while (*p && *p != ',')
			p++;
		if (!*p)
			break;
		*p++ = '\0';
	}

	if (!strncmp(buffer, "$GPGGA", 6)) {
		/*                                                           1 1111
		   0      1          2         3 4          5 6 7  8   9     0 1234
		   $GPGGA,184424.505,4924.2811,N,01107.8846,E,1,05,2.5,408.6,M,,,,0000*0C
		   UTC of Fix[1],Latitude[2],N/S[3],Longitude[4],E/W[5],Quality(0=inv,1=gps,2=dgps)[6],Satelites used[7],
		   HDOP[8],Altitude[9],"M"[10],height of geoid[11], "M"[12], time since dgps update[13], dgps ref station [14]
		 */
		if (*item[2] && *item[3] && *item[4] && *item[5]) {
			lat = g_ascii_strtod(item[2], NULL);
			priv->geo.lat = floor(lat / 100);
			lat -= priv->geo.lat * 100;
			priv->geo.lat += lat / 60;

			if (!strcasecmp(item[3],"S"))
				priv->geo.lat=-priv->geo.lat;

			lng = g_ascii_strtod(item[4], NULL);
			priv->geo.lng = floor(lng / 100);
			lng -= priv->geo.lng * 100;
			priv->geo.lng += lng / 60;

			if (!strcasecmp(item[5],"W"))
				priv->geo.lng=-priv->geo.lng;
			priv->valid=attr_position_valid_valid;
            dbg(2, "latitude '%2.4f' longitude %2.4f\n", priv->geo.lat, priv->geo.lng);

		} else
			priv->valid=attr_position_valid_invalid;
		if (*item[6])
			sscanf(item[6], "%d", &priv->status);
		if (*item[7])
		sscanf(item[7], "%d", &priv->sats_used);
		if (*item[8])
			sscanf(item[8], "%lf", &priv->hdop);
		if (*item[1])
			strcpy(priv->fixtime, item[1]);
		if (*item[9])
			sscanf(item[9], "%lf", &priv->height);

		g_free(priv->nmea_data);
		priv->nmea_data=priv->nmea_data_buf;
		priv->nmea_data_buf=NULL;
#ifndef _WIN32
		if (priv->file_type == file_type_file) {
			if (priv->watch) {
				vehicle_file_disable_watch(priv);
				event_add_timeout(priv->time, 0, priv->cbt);
			}
		}
#endif
	}
	if (!strncmp(buffer, "$GPVTG", 6)) {
		/* 0      1      2 34 5    6 7   8
		   $GPVTG,143.58,T,,M,0.26,N,0.5,K*6A
		   Course Over Ground Degrees True[1],"T"[2],Course Over Ground Degrees Magnetic[3],"M"[4],
		   Speed in Knots[5],"N"[6],"Speed in KM/H"[7],"K"[8]
		 */
		if (item[1] && item[7])
			valid = 1;
		if (i >= 10 && (*item[9] == 'A' || *item[9] == 'D'))
			valid = 1;
		if (valid) {
			priv->direction = g_ascii_strtod( item[1], NULL );
			priv->speed = g_ascii_strtod( item[7], NULL );
			dbg(2,"direction %lf, speed %2.1lf\n", priv->direction, priv->speed);
		}
	}
	if (!strncmp(buffer, "$GPRMC", 6)) {
		/*                                                           1     1
		   0      1      2 3        4 5         6 7     8     9      0     1
		   $GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A
		   Time[1],Active/Void[2],lat[3],N/S[4],long[5],W/E[6],speed in knots[7],track angle[8],date[9],
		   magnetic variation[10],magnetic variation direction[11]
		 */
		if (*item[2] == 'A')
			valid = 1;
		if (i >= 13 && (*item[12] == 'A' || *item[12] == 'D'))
			valid = 1;
		if (valid) {
			priv->direction = g_ascii_strtod( item[8], NULL );
			priv->speed = g_ascii_strtod( item[7], NULL );
			priv->speed *= 1.852;
			sscanf(item[9], "%02d%02d%02d",
				&priv->fixday,
				&priv->fixmonth,
				&priv->fixyear);
			priv->fixyear += 2000;
		}
		ret = 1;
	}
	if (!strncmp(buffer, "$GPGSV", 6) && i >= 4) {
	/*
		0 GSV	   Satellites in view
		1 2 	   Number of sentences for full data
		2 1 	   sentence 1 of 2
		3 08	   Number of satellites in view

		4 01	   Satellite PRN number
		5 40	   Elevation, degrees
		6 083	   Azimuth, degrees
		7 46	   SNR - higher is better
			   for up to 4 satellites per sentence
		*75	   the checksum data, always begins with *
	*/
		if (item[3]) {
			sscanf(item[3], "%d", &priv->sats_visible);
		}
		j=4;
		while (j+4 <= i && priv->current_count < 24) {
			struct gps_sat *sat=&priv->next[priv->next_count++];
			sat->prn=atoi(item[j]);
			sat->elevation=atoi(item[j+1]);
			sat->azimuth=atoi(item[j+2]);
			sat->snr=atoi(item[j+3]);
			j+=4;
		}
		if (!strcmp(item[1], item[2])) {
			priv->sats_signal=0;
			for (i = 0 ; i < priv->next_count ; i++) {
				priv->current[i]=priv->next[i];
				if (priv->current[i].snr)
					priv->sats_signal++;
			}
			priv->current_count=priv->next_count;
			priv->next_count=0;
		}
	}
	if (!strncmp(buffer, "$GPZDA", 6)) {
	/*
		0        1        2  3  4    5  6
		$GPZDA,hhmmss.ss,dd,mm,yyyy,xx,yy*CC
			hhmmss    HrMinSec(UTC)
			dd,mm,yyy Day,Month,Year
			xx        local zone hours -13..13
			yy        local zone minutes 0..59
	*/
		if (item[1] && item[2] && item[3] && item[4]) {
			// priv->fixtime = atof(item[1]);
			strcpy(priv->fixtime, item[1]);
			priv->fixday = atoi(item[2]);
			priv->fixmonth = atoi(item[3]);
			priv->fixyear = atoi(item[4]);
		}
	}
	if (!strncmp(buffer, "$IISMD", 6)) {
	/*
		0      1   2     3      4
		$IISMD,dir,press,height,temp*CC"
			dir 	  Direction (0-359)
			press	  Pressure (hpa, i.e. 1032)
			height    Barometric height above ground (meter)
			temp      Temperature (Degree Celsius)
	*/
		if (item[1]) {
			priv->magnetic_direction = g_ascii_strtod( item[1], NULL );
			dbg(1,"magnetic %d\n", priv->magnetic_direction);
		}
	}
	return ret;
}
Ejemplo n.º 5
0
/** @fn static void vehicle_file_io(struct vehicle_priv *priv)
*****************************************************************************
* @b Description: function to get data from GPS
*****************************************************************************
* @param      priv : pointer on the private data of the plugin
*****************************************************************************
* @remarks 
*****************************************************************************
**/
static void
vehicle_file_io(struct vehicle_priv *priv)
{
	int size, rc = 0;
	char *str, *tok;
    dbg(1, "vehicle_file_io : enter\n");

	if (priv->process_statefile) {
		unsigned char *data;
		priv->process_statefile=0;
		if (file_get_contents(priv->statefile, &data, &size)) {
			if (size > buffer_size)
				size=buffer_size;
			memcpy(priv->buffer, data, size);
			priv->buffer_pos=0;
			g_free(data);
		} else
			return;
	} else {
		size = read(priv->fd, priv->buffer + priv->buffer_pos, buffer_size - priv->buffer_pos - 1);
	}
	if (size <= 0) {
		switch (priv->on_eof) {
		case 0:
			vehicle_file_close(priv);
			vehicle_file_open(priv);
			break;
		case 1:
			vehicle_file_disable_watch(priv);
			break;
		case 2:
			exit(0);
			break;
		}
		return;
	}
	priv->buffer_pos += size;
	priv->buffer[priv->buffer_pos] = '\0';
	dbg(1, "size=%d pos=%d buffer='%s'\n", size,
	    priv->buffer_pos, priv->buffer);
	str = priv->buffer;
	while ((tok = strchr(str, '\n'))) {
		*tok++ = '\0';
		dbg(1, "line='%s'\n", str);
		rc +=vehicle_file_parse(priv, str);
		str = tok;
		if (priv->file_type == file_type_file && rc)
			break;
	}

	if (str != priv->buffer) {
		size = priv->buffer + priv->buffer_pos - str;
		memmove(priv->buffer, str, size + 1);
		priv->buffer_pos = size;
		dbg(1, "now pos=%d buffer='%s'\n",
		    priv->buffer_pos, priv->buffer);
	} else if (priv->buffer_pos == buffer_size - 1) {
		dbg(0,
		    "Overflow. Most likely wrong baud rate or no nmea protocol\n");
		priv->buffer_pos = 0;
	}
	if (rc)
		callback_list_call_attr_0(priv->cbl, attr_position_coord_geo);
}