Ejemplo n.º 1
0
nmea_s *
nmea_parse(char *sentence, int length, int check_checksum)
{
	nmea_t type = nmea_get_type(sentence);
	if (NMEA_UNKNOWN == type) {
		return (nmea_s *) NULL;
	}

	int n_vals;
	int val_index = 0;
	char *value;
	char *values[255];
	nmea_parser_module_s *parser;

	/* Validate */
	if (-1 == nmea_validate(sentence, length, check_checksum)) {
		return (nmea_s *) NULL;
	}

	/* Crop sentence from type word and checksum */
	char *val_string = _crop_sentence(sentence, length);
	if (NULL == val_string) {
	      	return (nmea_s *) NULL;
	}

	/* Split the sentence into values */
	n_vals = _split_string(val_string, values);
	if (0 == n_vals) {
		return (nmea_s *) NULL;
	}

	/* Get the right parser */
	parser = nmea_get_parser_by_type(type);
	if (NULL == parser) {
		return (nmea_s *) NULL;
	}

	/* Allocate memory for parsed data */
	parser->allocate_data((nmea_parser_s *) parser);
	if (NULL == parser->parser.data) {
		return (nmea_s *) NULL;
	}

	/* Set default values */
	parser->set_default((nmea_parser_s *) parser);
	parser->errors = 0;

	/* Loop through the values and parse them... */
	while (val_index < n_vals) {
		value = values[val_index];
		if (-1 == _is_value_set(value)) {
			val_index++;
			continue;
		}

		if (-1 == parser->parse((nmea_parser_s *) parser, value, val_index)) {
			parser->errors++;
		}

		val_index++;
	}

	parser->parser.data->type = type;
	parser->parser.data->errors = parser->errors;

	return parser->parser.data;
}
Ejemplo n.º 2
0
int MtkGps::parse_nmea(const char *str) 
{
	if (!nmea_is_valid(str))
		return -1;

	int ret, nmea_type = nmea_get_type(str);

	if (nmea_type == NMEA_SEN_GGA) {
		ret = nmea_parse_gpgga(str, &gga);
		if (ret == 0) {
			fix_time = gga.time;
			fix_msec = gga.millisec;
			valid |= NMEA_SEN_GGA;
		}
		return ret;
	}

	if (nmea_type == NMEA_SEN_RMC) {
		ret = nmea_parse_gprmc(str, &rmc);
		if (ret == 0) {
			double frac;
			latitude = rmc.latitude / 100.0;
			frac = modf(latitude, &latitude);
			latitude += frac/0.6;
			if (rmc.flags & NMEA_LAT_SOUTH)
				latitude = -latitude;

			longitude = rmc.longitude / 100.0;
			frac = modf(longitude, &longitude);
			longitude += frac/0.6;
			if (rmc.flags & NMEA_LON_WEST)
				longitude = -longitude;
			fix_time = rmc.time;
			fix_msec = rmc.millisec;
			fix_date = rmc.date;
			valid |= NMEA_SEN_RMC;
		}
		return ret;
	}

	if (nmea_type == NMEA_SEN_GLL) {
		ret = nmea_parse_gpgll(str, &gll);
		if (ret == 0) {
			fix_time = gll.time;
			fix_msec = gll.millisec;
			valid |= NMEA_SEN_GLL;
		}
		return ret;
	}

	if (nmea_type == NMEA_SEN_VTG) {
		ret = nmea_parse_gpvtg(str, &vtg);
		if (ret == 0)
			valid |= NMEA_SEN_VTG;
		return ret;
	}

	if (nmea_type == NMEA_SEN_GSA) {
		ret = nmea_parse_gpgsa(str, &gsa);
		if (ret == 0)
			valid |= NMEA_SEN_GSA;
		return ret;
	}

	if (nmea_type == NMEA_SEN_ZDA) {
		ret = nmea_parse_gpzda(str, &zda);
		if (ret == 0) {
			fix_date = zda.date;
			fix_time = zda.time;
			fix_msec = zda.millisec;
			valid |= NMEA_SEN_ZDA;
		}
		return ret;
	}

	if (nmea_type == NMEA_SEN_GSV) {
		ret = nmea_parse_gpgsv(str, gsv, &ngsv, &igsv);
		if (ret == 0)
			valid |= NMEA_SEN_GSV;
		return ret;
	}

	if (nmea_type == NMEA_SEN_MCHN) {
		ret = nmea_parse_mtkchn(str, chn);
		if (ret == 0)
			valid |= NMEA_SEN_MCHN;
		return ret;
	}

	// firmware release info
	if (nmea_type == NMEA_SEN_MTK) {
		int type = getMtkPType(nmea);
		if (type == PMTK_DT_RELEASE) {
			if (release != NULL)
				free((void *)release);
			char *end = strchr(nmea, '*');
			if (end)
				*end = '\0';
			release = strdup(nmea + 9);
			return 0;
		}
	}
	return 0;
}