/**
 * \brief Parse GGA packet from buffer.
 * @param buff a constant character pointer of packet buffer.
 * @param buff_sz buffer size.
 * @param pack a pointer of packet which will filled by function.
 * @return 1 (true) - if parsed successfully or 0 (false) - if fail.
 */
int nmea_parse_GPGGA(const char *buff, int buff_sz, nmeaGPGGA *pack)
{
    char time_buff[NMEA_TIMEPARSE_BUF];

    NMEA_ASSERT(buff && pack);

    memset(pack, 0, sizeof(nmeaGPGGA));

    nmea_trace_buff(buff, buff_sz);

    if(14 != nmea_scanf(buff, buff_sz,
        "$GPGGA,%s,%f,%C,%f,%C,%d,%d,%f,%f,%C,%f,%C,%f,%d*",
        &(time_buff[0]),
        &(pack->lat), &(pack->ns), &(pack->lon), &(pack->ew),
        &(pack->sig), &(pack->satinuse), &(pack->HDOP), &(pack->elv), &(pack->elv_units),
        &(pack->diff), &(pack->diff_units), &(pack->dgps_age), &(pack->dgps_sid)))
    {
        nmea_error("GPGGA parse error!");
        return 0;
    }

    if(0 != _nmea_parse_time(&time_buff[0], (int)strlen(&time_buff[0]), &(pack->utc)))
    {
        nmea_error("GPGGA time parse error!");
        return 0;
    }

    return 1;
}
Exemple #2
0
/**
 * \brief Parse RMC packet from buffer.
 * @param buff a constant character pointer of packet buffer.
 * @param buff_sz buffer size.
 * @param pack a pointer of packet which will filled by function.
 * @return 1 (true) - if parsed successfully or 0 (false) - if fail.
 */
int nmea_parse_GPRMC( const char *buff, int buff_sz, nmeaGPRMC *pack )
{
  int nsen;
  char type;
  char time_buff[NMEA_TIMEPARSE_BUF];

  NMEA_ASSERT( buff && pack );

  memset( pack, 0, sizeof( nmeaGPRMC ) );

  nmea_trace_buff( buff, buff_sz );

  nsen = nmea_scanf( buff, buff_sz,
                     "$G%CRMC,%s,%C,%f,%C,%f,%C,%f,%f,%2d%2d%2d,%f,%C,%C*",
                     &( type ), &( time_buff[0] ),
                     &( pack->status ), &( pack->lat ), &( pack->ns ), &( pack->lon ), &( pack->ew ),
                     &( pack->speed ), &( pack->direction ),
                     &( pack->utc.day ), &( pack->utc.mon ), &( pack->utc.year ),
                     &( pack->declination ), &( pack->declin_ew ), &( pack->mode ) );

  if ( nsen != 14 && nsen != 15 )
  {
    nmea_error( "GPRMC parse error!" );
    return 0;
  }

  if ( type != 'P' && type != 'N' )
  {
    nmea_error( "G?RMC invalid type " );
    return 0;
  }

  if ( 0 != _nmea_parse_time( &time_buff[0], ( int )strlen( &time_buff[0] ), &( pack->utc ) ) )
  {
    nmea_error( "GPRMC time parse error!" );
    return 0;
  }

  if ( pack->utc.year < 90 )
    pack->utc.year += 100;
  pack->utc.mon -= 1;

  return 1;
}
Exemple #3
0
/**
 * Parse a GPRMC sentence from a string
 *
 * @param s the string
 * @param len the length of the string
 * @param pack a pointer to the result structure
 * @return 1 (true) - if parsed successfully or 0 (false) otherwise.
 */
int nmea_parse_GPRMC(const char *s, const int len, nmeaGPRMC *pack) {
	int token_count;
	char time_buff[NMEA_TIMEPARSE_BUF];
	int date;
	size_t time_buff_len = 0;

	assert(s);
	assert(pack);

	nmea_trace_buff(s, len);

	/*
	 * Clear before parsing, to be able to detect absent fields
	 */
	time_buff[0] = '\0';
	date = -1;
	pack->present = 0;
	pack->utc.year = -1;
	pack->utc.mon = -1;
	pack->utc.day = -1;
	pack->utc.hour = -1;
	pack->utc.min = -1;
	pack->utc.sec = -1;
	pack->utc.hsec = -1;
	pack->status = 0;
	pack->lat = NAN;
	pack->ns = 0;
	pack->lon = NAN;
	pack->ew = 0;
	pack->speed = NAN;
	pack->track = NAN;
	pack->magvar = NAN;
	pack->magvar_ew = 0;
	pack->mode = 0;

	/* parse */
	token_count = nmea_scanf(s, len, "$GPRMC,%s,%c,%f,%c,%f,%c,%f,%f,%d,%f,%c,%c*", &time_buff[0], &pack->status,
			&pack->lat, &pack->ns, &pack->lon, &pack->ew, &pack->speed, &pack->track, &date,
			&pack->magvar, &pack->magvar_ew, &pack->mode);

	/* see that we have enough tokens */
	if ((token_count != 11) && (token_count != 12)) {
		nmea_error("GPRMC parse error: need 11 or 12 tokens, got %d in %s", token_count, s);
		return 0;
	}

	/* determine which fields are present and validate them */

	time_buff_len = strlen(&time_buff[0]);
	if (time_buff_len) {
		if (!_nmea_parse_time(&time_buff[0], time_buff_len, &pack->utc)) {
			return 0;
		}

		if (!validateTime(&pack->utc)) {
			return 0;
		}

		nmea_INFO_set_present(&pack->present, UTCTIME);
	}

	if (!pack->status) {
		pack->status = 'V';
	} else {
		pack->status = toupper(pack->status);
		if (!((pack->status == 'A') || (pack->status == 'V'))) {
			nmea_error("GPRMC parse error: invalid status (%c)", pack->status);
			return 0;
		}
	}
	if (!isnan(pack->lat) && (pack->ns)) {
		if (!validateNSEW(&pack->ns, true)) {
			return 0;
		}

		nmea_INFO_set_present(&pack->present, LAT);
	}
	if (!isnan(pack->lon) && (pack->ew)) {
		if (!validateNSEW(&pack->ew, false)) {
			return 0;
		}

		nmea_INFO_set_present(&pack->present, LON);
	}
	if (!isnan(pack->speed)) {
		nmea_INFO_set_present(&pack->present, SPEED);
	}
	if (!isnan(pack->track)) {
		nmea_INFO_set_present(&pack->present, TRACK);
	}

	if (date != -1) {
		if (!_nmea_parse_date(date, &pack->utc)) {
			return 0;
		}

		if (!validateDate(&pack->utc)) {
			return 0;
		}

		nmea_INFO_set_present(&pack->present, UTCDATE);
	}

	if (!isnan(pack->magvar) && (pack->magvar_ew)) {
		if (!validateNSEW(&pack->magvar_ew, false)) {
			return 0;
		}

		nmea_INFO_set_present(&pack->present, MAGVAR);
	}
	if (token_count == 11) {
		pack->mode = 'A';
	} else {
		if (!pack->mode) {
			pack->mode = 'N';
		} else {
			if (!validateMode(&pack->mode)) {
				return 0;
			}
		}
	}

	return 1;
}
Exemple #4
0
/**
 * Parse a GPGGA sentence from a string
 *
 * @param s the string
 * @param len the length of the string
 * @param pack a pointer to the result structure
 * @return 1 (true) - if parsed successfully or 0 (false) otherwise.
 */
int nmea_parse_GPGGA(const char *s, const int len, nmeaGPGGA *pack) {
	int token_count;
	char time_buff[NMEA_TIMEPARSE_BUF];
	size_t time_buff_len = 0;

	assert(s);
	assert(pack);

	nmea_trace_buff(s, len);

	/*
	 * Clear before parsing, to be able to detect absent fields
	 */
	time_buff[0] = '\0';
	pack->present = 0;
	pack->utc.hour = -1;
	pack->utc.min = -1;
	pack->utc.sec = -1;
	pack->utc.hsec = -1;
	pack->lat = NAN;
	pack->ns = 0;
	pack->lon = NAN;
	pack->ew = 0;
	pack->sig = -1;
	pack->satinuse = -1;
	pack->HDOP = NAN;
	pack->elv = NAN;
	pack->elv_units = 0;
	pack->diff = 0;			/* ignored */
	pack->diff_units = 0;	/* ignored */
	pack->dgps_age = 0;		/* ignored */
	pack->dgps_sid = 0;		/* ignored */

	/* parse */
	token_count = nmea_scanf(s, len, "$GPGGA,%s,%f,%c,%f,%c,%d,%d,%f,%f,%c,%f,%c,%f,%d*", &time_buff[0], &pack->lat,
			&pack->ns, &pack->lon, &pack->ew, &pack->sig, &pack->satinuse, &pack->HDOP, &pack->elv, &pack->elv_units,
			&pack->diff, &pack->diff_units, &pack->dgps_age, &pack->dgps_sid);

	/* see that we have enough tokens */
	if (token_count != 14) {
		nmea_error("GPGGA parse error: need 14 tokens, got %d in %s", token_count, s);
		return 0;
	}

	/* determine which fields are present and validate them */

	time_buff_len = strlen(&time_buff[0]);
	if (time_buff_len > (NMEA_TIMEPARSE_BUF - 1))
		time_buff_len = NMEA_TIMEPARSE_BUF - 1;
	if (time_buff_len) {
		if (!_nmea_parse_time(&time_buff[0], time_buff_len, &pack->utc)) {
			return 0;
		}

		if (!validateTime(&pack->utc)) {
			return 0;
		}

		nmea_INFO_set_present(&pack->present, UTCTIME);
	}
	if (!isnan(pack->lat) && (pack->ns)) {
		if (!validateNSEW(&pack->ns, true)) {
			return 0;
		}

		nmea_INFO_set_present(&pack->present, LAT);
	}
	if (!isnan(pack->lon) && (pack->ew)) {
		if (!validateNSEW(&pack->ew, false)) {
			return 0;
		}

		nmea_INFO_set_present(&pack->present, LON);
	}
	if (pack->sig != -1) {
		if (!((pack->sig >= NMEA_SIG_FIRST) && (pack->sig <= NMEA_SIG_LAST))) {
			nmea_error("GPGGA parse error: invalid signal %d, expected [%d, %d]", pack->sig, NMEA_SIG_FIRST, NMEA_SIG_LAST);
			return 0;
		}

		nmea_INFO_set_present(&pack->present, SIG);
	}
	if (pack->satinuse != -1) {
		nmea_INFO_set_present(&pack->present, SATINUSECOUNT);
	}
	if (!isnan(pack->HDOP)) {
		nmea_INFO_set_present(&pack->present, HDOP);
	}
	if (!isnan(pack->elv) && (pack->elv_units)) {
		if (pack->elv_units != 'M') {
			nmea_error("GPGGA parse error: invalid elevation unit (%c)", pack->elv_units);
			return 0;
		}

		nmea_INFO_set_present(&pack->present, ELV);
	}
	/* ignore diff and diff_units */
	/* ignore dgps_age and dgps_sid */

	return 1;
}